diff --git a/DynObj.cpp b/DynObj.cpp index 1fd73538..1402faef 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1626,21 +1626,11 @@ TDynamicObject::TDynamicObject() { // McZapkie-270202 Controller = AIdriver; bDisplayCab = false; // 030303 - bBrakeAcc = false; NextConnected = PrevConnected = NULL; NextConnectedNo = PrevConnectedNo = 2; // ABu: Numery sprzegow. 2=nie podłączony - asName = ""; bEnabled = true; MyTrack = NULL; // McZapkie-260202 -/* - dRailLength = 25.0; - for (int i = 0; i < MaxAxles; i++) - dRailPosition[i] = 0.0; - for (int i = 0; i < MaxAxles; i++) - dWheelsPosition[i] = 0.0; // będzie wczytane z MMD - iAxles = 0; -*/ dWheelAngle[0] = 0.0; dWheelAngle[1] = 0.0; dWheelAngle[2] = 0.0; @@ -1649,11 +1639,6 @@ TDynamicObject::TDynamicObject() { NoVoltTime = 0; dDoorMoveL = 0.0; dDoorMoveR = 0.0; - // for (int i=0;i<8;i++) - //{ - // DoorSpeedFactor[i]=random(150); - // DoorSpeedFactor[i]=(DoorSpeedFactor[i]+100)/100; - //} mdModel = NULL; mdKabina = NULL; // smWiazary[0]=smWiazary[1]=NULL; @@ -1669,9 +1654,6 @@ TDynamicObject::TDynamicObject() { smBogie[0] = smBogie[1] = NULL; bogieRot[0] = bogieRot[1] = vector3(0, 0, 0); modelRot = vector3(0, 0, 0); - eng_vol_act = 0.8; - eng_dfrq = 0; - eng_frq_act = 1; cp1 = cp2 = sp1 = sp2 = 0; iDirection = 1; // stoi w kierunku tradycyjnym (0, gdy jest odwrócony) iAxleFirst = 0; // numer pierwszej osi w kierunku ruchu (przełączenie @@ -1690,9 +1672,6 @@ TDynamicObject::TDynamicObject() { iAnimType[ANIM_PANTS] = 0; // 5-pantografy (2) iAnimType[ANIM_STEAMS] = 0; // 6-tłoki (napęd parowozu) iAnimations = 0; // na razie nie ma żadnego -/* - pAnimations = NULL; -*/ pAnimated = NULL; fShade = 0.0; // standardowe oświetlenie na starcie iHornWarning = 1; // numer syreny do użycia po otrzymaniu sygnału do jazdy @@ -1713,30 +1692,10 @@ TDynamicObject::TDynamicObject() { fAdjustment = 0.0; // korekcja odległości pomiędzy wózkami (np. na łukach) } -TDynamicObject::~TDynamicObject() -{ // McZapkie-250302 - zamykanie logowania - // parametrow fizycznych - SafeDelete(Mechanik); - SafeDelete(MoverParameters); - // Ra: wyłączanie dźwięków powinno być dodane w ich destruktorach, ale się - // sypie - /* to też się sypie - for (int i=0;iLoadStatus &= 3; // po zakończeniu będzie równe zero }; -/* -double ComputeRadius(double p1x, double p1z, double p2x, double p2z, - double p3x, double p3z, double p4x, double p4z) -{ - - double v1z= p1x-p2x; - double v1x= p1z-p2z; - double v4z= p3x-p4x; - double v4x= p3z-p4z; - double A1= p2z-p1z; - double B1= p1x-p2x; - double C1= -p1z*B1-p1x*A1; - double A2= p4z-p3z; - double B2= p3x-p4x; - double C2= -p3z*B1-p3x*A1; - double y= (A1*C2/A2-C1)/(B1-A1*B2/A2); - double x= (-B2*y-C2)/A2; -} -*/ -double TDynamicObject::ComputeRadius(vector3 p1, vector3 p2, vector3 p3, vector3 p4) -{ - // vector3 v1 - - // TLine l1= TLine(p1,p1-p2); - // TLine l4= TLine(p4,p4-p3); - // TPlane p1= l1.GetPlane(); - // vector3 pt; - // CrossPoint(pt,l4,p1); - double R = 0.0; - vector3 p12 = p1 - p2; - vector3 p34 = p3 - p4; - p12 = CrossProduct(p12, vector3(0.0, 0.1, 0.0)); - p12 = Normalize(p12); - p34 = CrossProduct(p34, vector3(0.0, 0.1, 0.0)); - p34 = Normalize(p34); - if (fabs(p1.x - p2.x) > 0.01) - { - if (fabs(p12.x - p34.x) > 0.001) - R = (p1.x - p4.x) / (p34.x - p12.x); - } - else - { - if (fabs(p12.z - p34.z) > 0.001) - R = (p1.z - p4.z) / (p34.z - p12.z); - } - return (R); -} - -/* -double TDynamicObject::ComputeRadius() -{ - double L=0; - double d=0; - d=sqrt(SquareMagnitude(Axle0.pPosition-Axle1.pPosition)); - L=Axle1.GetLength(Axle1.pPosition,Axle1.pPosition-Axle2.pPosition,Axle0.pPosition-Axle3.pPosition,Axle0.pPosition); - - double eps=0.01; - double R= 0; - double L_d; - if ((L>0) || (d>0)) - { - L_d= L-d; - if (L_d>eps) - { - R=L*sqrt(L/(24*(L_d))); - } - } - return R; -} -*/ - -/* Ra: na razie nie potrzebne -void TDynamicObject::UpdatePos() -{ - MoverParameters->Loc.X= -vPosition.x; - MoverParameters->Loc.Y= vPosition.z; - MoverParameters->Loc.Z= vPosition.y; -} -*/ - /* Ra: Powinny być dwie funkcje wykonujące aktualizację fizyki. Jedna wykonująca @@ -3703,13 +3582,18 @@ void TDynamicObject::RenderSounds() { sSand.stop(); } + auto brakeforceratio { 0.0 }; if( //( false == mvOccupied->SlippingWheels ) && ( MoverParameters->UnitBrakeForce > 10.0 ) - && ( GetVelocity() > 0.05 ) ) { + && ( MoverParameters->Vel > 0.05 ) ) { + brakeforceratio = + clamp( + MoverParameters->UnitBrakeForce / ( MoverParameters->BrakeForceR( 1.0, MoverParameters->Vel ) / ( MoverParameters->NAxles * std::max( 1, MoverParameters->NBpA ) ) ), + 0.0, 1.0 ); rsBrake - .pitch( rsBrake.m_frequencyfactor * GetVelocity() + rsBrake.m_frequencyoffset ) - .gain( rsBrake.m_amplitudefactor * std::sqrt( ( GetVelocity() * MoverParameters->UnitBrakeForce ) ) + rsBrake.m_amplitudeoffset ) + .pitch( rsBrake.m_frequencyoffset + MoverParameters->Vel * rsBrake.m_frequencyfactor ) + .gain( rsBrake.m_amplitudeoffset + std::sqrt( brakeforceratio * interpolate( 0.4, 1.0, ( MoverParameters->Vel / ( 1 + MoverParameters->Vmax ) ) ) ) ) .play( sound_flags::exclusive | sound_flags::looping ); } else { @@ -3823,51 +3707,9 @@ void TDynamicObject::RenderSounds() { volume = rsOuterNoise.m_amplitudefactor * MoverParameters->Vel + rsOuterNoise.m_amplitudeoffset; frequency = rsOuterNoise.m_frequencyfactor * MoverParameters->Vel + rsOuterNoise.m_frequencyoffset; - if( false == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) { - // McZpakie-221103: halas zalezny od kola - switch( MyTrack->eEnvironment ) { - case e_tunnel: { - volume *= 3; - frequency *= 0.95; - break; - } - case e_canyon: { - volume *= 1.1; - break; - } - case e_bridge: { - volume *= 2; - frequency *= 0.98; - break; - } - default: { - break; - } - } - } - else { - // uszkodzone kolo (podkucie) - switch( MyTrack->eEnvironment ) { - case e_tunnel: { - volume *= 2; - break; - } - case e_canyon: { - volume *= 1.1; - break; - } - case e_bridge: { - volume *= 1.5; - break; - } - default: { - break; - } - } - } - if( std::abs( MoverParameters->nrot ) > 0.01 ) { + if( brakeforceratio > 0.0 ) { // hamulce wzmagaja halas - volume *= 1 + 0.25 * ( MoverParameters->UnitBrakeForce / ( 1 + MoverParameters->MaxBrakeForce ) ); + volume *= 1 + 0.25 * brakeforceratio; } // scale volume by track quality volume *= ( 20.0 + MyTrack->iDamageFlag ) / 21; @@ -3889,6 +3731,17 @@ void TDynamicObject::RenderSounds() { // don't play the optional ending sound if the listener switches views rsOuterNoise.stop( false == FreeFlyModeFlag ); } + // flat spot sound + if( ( GetVelocity() > 1.0 ) + && ( true == TestFlag( MoverParameters->DamageFlag, dtrain_wheelwear ) ) ) { + m_wheelflat + .pitch( m_wheelflat.m_frequencyoffset + std::abs( MoverParameters->nrot ) * m_wheelflat.m_frequencyfactor ) + .gain( m_wheelflat.m_amplitudeoffset + 0.4 + 0.6 * ( MoverParameters->Vel * m_wheelflat.m_amplitudefactor ) ) + .play( sound_flags::exclusive | sound_flags::looping ); + } + else { + m_wheelflat.stop(); + } // youBy: dzwiek ostrych lukow i ciasnych zwrotek if( ( ts.R * ts.R > 1 ) @@ -4921,6 +4774,14 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, rsOuterNoise.m_frequencyfactor /= ( 1 + MoverParameters->Vmax ); } + else if( token == "wheelflat:" ) { + // szum podczas jazdy: + m_wheelflat.deserialize( parser, sound_type::single, sound_parameters::frequency ); + m_wheelflat.owner( this ); + + m_wheelflat.m_amplitudefactor /= ( 1 + MoverParameters->Vmax ); + } + } while( ( token != "" ) && ( token != "endsounds" ) ); @@ -4981,8 +4842,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, // hamowanie zwykle: rsBrake.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency ); rsBrake.owner( this ); - - rsBrake.m_amplitudefactor /= ( 1 + MoverParameters->MaxBrakeForce * 1000 ); + // NOTE: can't pre-calculate amplitude normalization based on max brake force, as this varies depending on vehicle speed rsBrake.m_frequencyfactor /= ( 1 + MoverParameters->Vmax ); } else if( token == "slipperysound:" ) { @@ -5079,6 +4939,12 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, } } // other sounds + if( true == m_wheelflat.empty() ) { + m_wheelflat.deserialize( "lomotpodkucia.wav 0.23 0.0", sound_type::single, sound_parameters::frequency ); + m_wheelflat.owner( this ); + + m_wheelflat.m_amplitudefactor /= ( 1 + MoverParameters->Vmax ); + } if( true == rscurve.empty() ) { // hunter-111211: domyslne, gdy brak rscurve.deserialize( "curve.wav", sound_type::single ); diff --git a/DynObj.h b/DynObj.h index d245e63e..c0cf4367 100644 --- a/DynObj.h +++ b/DynObj.h @@ -308,7 +308,6 @@ private: // methods void ABuLittleUpdate(double ObjSqrDist); - double ComputeRadius( Math3D::vector3 p1, Math3D::vector3 p2, Math3D::vector3 p3, Math3D::vector3 p4); void ABuBogies(); void ABuModelRoll(); void TurnOff(); @@ -348,46 +347,25 @@ private: TButton btMechanik1; TButton btMechanik2; -// int iAxles; // McZapkie: to potem mozna skasowac i zastapic iNumAxles double dRailLength { 0.0 }; std::vector m_axlesounds; - powertrain_sounds m_powertrainsounds; // engine sounds -/* - sound_source dsbDieselIgnition { sound_placement::engine }; // moved from cab - sound_source rsSilnik { sound_placement::engine }; - double enginevolume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal - sound_source m_tractionmotor { sound_placement::external }; - sound_source dsbRelay { sound_placement::engine }; - sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab - sound_source dsbWejscie_na_drugi_uklad { sound_placement::engine }; // moved from cab - sound_source rsPrzekladnia { sound_placement::engine }; - sound_source rsEngageSlippery { sound_placement::engine }; // moved from cab - sound_source rsDieselInc { sound_placement::engine }; // youBy - float m_lastenginerevolutions { -1.f }; // helper, cached rpm of the engine - float m_enginerevolutionschange { 0.f }; // recent change of engine revolutions - sound_source sTurbo { sound_placement::engine }; - sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302 - sound_source sConverter { sound_placement::engine }; - sound_source sCompressor { sound_placement::engine }; // NBMX wrzesien 2003 - sound_source sSmallCompressor { sound_placement::engine }; -*/ + powertrain_sounds m_powertrainsounds; sound_source sConverter { sound_placement::engine }; sound_source sCompressor { sound_placement::engine }; // NBMX wrzesien 2003 sound_source sSmallCompressor { sound_placement::engine }; // braking sounds sound_source dsbPneumaticRelay { sound_placement::external }; + sound_source rsBrake { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab + sound_source sBrakeAcc { sound_placement::external }; + bool bBrakeAcc { false }; + sound_source rsPisk { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // McZapkie-260302 sound_source rsUnbrake { sound_placement::external }; // yB - odglos luzowania float m_lastbrakepressure { -1.f }; // helper, cached level of pressure in brake cylinder float m_brakepressurechange { 0.f }; // recent change of pressure in brake cylinder sound_source sReleaser { sound_placement::external }; sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab sound_source sSand { sound_placement::external }; - sound_source rsBrake { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab - sound_source sBrakeAcc { sound_placement::external }; - bool bBrakeAcc; - sound_source rsPisk { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // McZapkie-260302 - sound_source rsDerailment { sound_placement::external, 250.f }; // McZapkie-051202 // moving part and other external sounds std::array m_couplersounds; // always front and rear std::vector m_pantographsounds; // typically 2 but can be less (or more?) @@ -396,11 +374,10 @@ private: sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source rsOuterNoise { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; + sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy + sound_source rsDerailment { sound_placement::external, 250.f }; // McZapkie-051202 - double eng_vol_act; - double eng_frq_act; - double eng_dfrq; Math3D::vector3 modelShake; bool renderme; // yB - czy renderowac diff --git a/Event.cpp b/Event.cpp index 534f618b..85489d22 100644 --- a/Event.cpp +++ b/Event.cpp @@ -407,14 +407,15 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org) *parser >> token; break; case tp_Sound: - // Params[0].asRealSound->Init(asNodeName.c_str(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble()); - // McZapkie-070502: dzwiek przestrzenny (ale do poprawy) - // Params[1].asdouble=Parser->GetNextSymbol().ToDouble(); - // Params[2].asdouble=Parser->GetNextSymbol().ToDouble(); - // Params[3].asdouble=Parser->GetNextSymbol().ToDouble(); //polozenie X,Y,Z - do poprawy! parser->getTokens(); *parser >> Params[0].asInt; // 0: wylaczyc, 1: wlaczyc; -1: wlaczyc zapetlone + Params[1].asdouble = 0.0; parser->getTokens(); + if( parser->peek() != "endevent" ) { + // optional parameter, radio channel to receive/broadcast the sound + *parser >> Params[1].asdouble; + parser->getTokens(); + } *parser >> token; break; case tp_Exit: @@ -1032,7 +1033,14 @@ event_manager::CheckQuery() { break; } case 1: { - m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive ); + if( m_workevent->Params[ 1 ].asdouble > 0.0 ) { + Global::pWorld->radio_message( + m_workevent->Params[ 9 ].tsTextSound, + static_cast( m_workevent->Params[ 1 ].asdouble ) ); + } + else { + m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive ); + } break; } case -1: { diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index b7570740..2977f8e6 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3881,31 +3881,22 @@ double TMoverParameters::BrakeForceP(double press, double velocity) // Q: 20160713 // oblicza siłę na styku koła i szyny // ************************************************************************************************* -double TMoverParameters::BrakeForce(const TTrackParam &Track) -{ - double K, Fb, NBrakeAxles, sm = 0; - // const OerlikonForceFactor=1.5; +double TMoverParameters::BrakeForce( TTrackParam const &Track ) { - if (NPoweredAxles > 0) - NBrakeAxles = NPoweredAxles; - else - NBrakeAxles = NAxles; - switch (LocalBrake) - { - case NoBrake: - K = 0; - break; - case ManualBrake: - K = MaxBrakeForce * ManualBrakeRatio(); - break; - case HydraulicBrake: - K = MaxBrakeForce * LocalBrakeRatio(); - break; - case PneumaticBrake: - if (Compressor < MaxBrakePress[3]) - K = MaxBrakeForce * LocalBrakeRatio() / 2.0; - else - K = 0; + double K{ 0 }, Fb{ 0 }, sm{ 0 }; + + switch( LocalBrake ) { + case ManualBrake: { + K = MaxBrakeForce * ManualBrakeRatio(); + break; + } + case HydraulicBrake: { + K = MaxBrakeForce * LocalBrakeRatio(); + break; + } + default: { + break; + } } if (MBrake == true) @@ -3913,8 +3904,6 @@ double TMoverParameters::BrakeForce(const TTrackParam &Track) K = MaxBrakeForce * ManualBrakeRatio(); } - // 0.03 - u = ((BrakePress * P2FTrans) - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj; if (u * BrakeRigEff > Ntotal) // histereza na nacisku klockow Ntotal = u * BrakeRigEff; @@ -3925,6 +3914,11 @@ double TMoverParameters::BrakeForce(const TTrackParam &Track) Ntotal = u * (2.0 - BrakeRigEff); } + auto const NBrakeAxles { ( + NPoweredAxles > 0 ? + NPoweredAxles : + NAxles ) }; + if (NBrakeAxles * NBpA > 0) { if (Ntotal > 0) // nie luz diff --git a/Train.cpp b/Train.cpp index cf44f4c9..bf2fc36a 100644 --- a/Train.cpp +++ b/Train.cpp @@ -312,7 +312,6 @@ TTrain::TTrain() { //----- pMechSittingPosition = vector3(0, 0, 0); // ABu: 180404 InstrumentLightActive = false; // ABu: 030405 - iRadioChannel = 0; fTachoTimer = 0.0; // włączenie skoków wskazań prędkościomierza // @@ -3317,7 +3316,7 @@ void TTrain::UpdateMechPosition(double dt) vector3 TTrain::GetWorldMechPosition() { - vector3 position = DynamicObject->mMatrix *pMechPosition; // położenie względem środka pojazdu w układzie scenerii + vector3 position = DynamicObject->mMatrix * pMechPosition; // położenie względem środka pojazdu w układzie scenerii position += DynamicObject->GetPosition(); return position; } @@ -5127,6 +5126,16 @@ bool TTrain::Update( double const Deltatime ) // sounds update_sounds( Deltatime ); + if( false == m_radiomessages.empty() ) { + // erase completed radio messages from the list + m_radiomessages.erase( + std::remove_if( + std::begin( m_radiomessages ), std::end( m_radiomessages ), + []( sound_source &source ) { + return ( false == source.is_playing() ); } ), + std::end( m_radiomessages ) ); + } + return true; //(DynamicObject->Update(dt)); } // koniec update @@ -5567,7 +5576,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) &dsbSwitch, &dsbPneumaticSwitch, &rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsSBHissU, &rsFadeSound, &rsRunningNoise, - &dsbHasler, &dsbBuzzer, &dsbSlipAlarm + &dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_radiosound }; for( auto sound : sounds ) { sound->offset( nullvector ); @@ -5751,6 +5760,13 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) if( dsbBuzzer.offset() == nullvector ) { dsbBuzzer.offset( btLampkaCzuwaka.model_offset() ); } + // radio has two potential items which can provide the position + if( m_radiosound.offset() == nullvector ) { + m_radiosound.offset( ggRadioButton.model_offset() ); + } + if( m_radiosound.offset() == nullvector ) { + m_radiosound.offset( btLampkaRadio.model_offset() ); + } auto const localbrakeoffset { ggLocalBrake.model_offset() }; std::vector localbrakesounds = { &rsSBHiss, &rsSBHissU @@ -5873,6 +5889,26 @@ void TTrain::DynamicSet(TDynamicObject *d) } }; +void +TTrain::radio_message( sound_source *Message, int const Channel ) { + + if( ( false == mvOccupied->Radio ) + || ( iRadioChannel != Channel ) ) { + // skip message playback if the radio isn't able to receive it + return; + } + auto const radiorange { 7500 * 7500 }; + if( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > radiorange ) { + return; + } + + m_radiomessages.emplace_back( m_radiosound ); + // assign sound to the template and play it + m_radiomessages.back() + .copy_sounds( *Message ) + .play( sound_flags::exclusive ); +} + void TTrain::Silence() { // wyciszenie dźwięków przy wychodzeniu #ifdef EU07_USE_OLD_SOUNDCODE diff --git a/Train.h b/Train.h index 57a33920..b91fa1b8 100644 --- a/Train.h +++ b/Train.h @@ -420,6 +420,8 @@ public: // reszta może by?publiczna sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source dsbSlipAlarm { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // Bombardier 011010: alarm przy poslizgu dla 181/182 + sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages + std::vector m_radiomessages; // list of currently played radio messages int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? @@ -468,7 +470,7 @@ private: float fPPress, fNPress; // float fSPPress, fSNPress; int iSekunda; // Ra: sekunda aktualizacji pr?dko?ci - int iRadioChannel; // numer aktualnego kana?u radiowego + int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego TPythonScreens pyScreens; public: @@ -476,6 +478,8 @@ private: static std::vector const fPress_labels; float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych int RadioChannel() { return iRadioChannel; }; + // plays provided sound from position of the radio + void radio_message( sound_source *Message, int const Channel ); inline TDynamicObject *Dynamic() { return DynamicObject; }; inline TDynamicObject const *Dynamic() const { return DynamicObject; }; inline TMoverParameters *Controlled() { return mvControlled; }; diff --git a/World.cpp b/World.cpp index d7901166..6721f7a6 100644 --- a/World.cpp +++ b/World.cpp @@ -2073,6 +2073,15 @@ void TWorld::CreateE3D(std::string const &Path, bool Dynamic) }; //--------------------------------------------------------------------------- +// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel +void +TWorld::radio_message( sound_source *Message, int const Channel ) { + + if( Train != nullptr ) { + Train->radio_message( Message, Channel ); + } +} + void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now) { // ewentualna zmiana kabiny użytkownikowi if (Train) diff --git a/World.h b/World.h index 09c9dae9..ccfe2d3f 100644 --- a/World.h +++ b/World.h @@ -85,10 +85,6 @@ class TWorld // NOTE: direct access is a shortcut, but world etc needs some restructuring regardless friend opengl_renderer; - void InOutKey( bool const Near = true ); - void FollowView(bool wycisz = true); - void DistantView( bool const Near = false ); - public: // types @@ -99,14 +95,16 @@ TWorld(); ~TWorld(); // methods + void CreateE3D( std::string const &dir = "", bool dyn = false ); bool Init( GLFWwindow *w ); bool InitPerformed() { return m_init; } - GLFWwindow *window; - void OnKeyDown(int cKey); - // void UpdateWindow(); - void OnMouseMove(double x, double y); - void OnCommandGet(multiplayer::DaneRozkaz *pRozkaz); bool Update(); + void OnKeyDown( int cKey ); + void OnMouseMove( double x, double y ); + void OnCommandGet( multiplayer::DaneRozkaz *pRozkaz ); + // passes specified sound to all vehicles within range as a radio message broadcasted on specified channel + void radio_message( sound_source *Message, int const Channel ); + void CabChange( TDynamicObject *old, TDynamicObject *now ); void TrainDelete(TDynamicObject *d = NULL); TTrain const * train() const { return Train; } @@ -115,11 +113,18 @@ TWorld(); // calculates current season of the year based on set simulation date void compute_season( int const Yearday ) const; +// members + private: void Update_Environment(); void Update_Camera( const double Deltatime ); void Update_UI(); void ResourceSweep(); + // handles vehicle change flag + void ChangeDynamic(); + void InOutKey( bool const Near = true ); + void FollowView( bool wycisz = true ); + void DistantView( bool const Near = false ); TCamera Camera; TCamera DebugCamera; @@ -140,13 +145,8 @@ private: double VelPrev; // poprzednia prędkość int tprev; // poprzedni czas double Acc; // przyspieszenie styczne - bool m_init{ false }; // indicates whether initial update of the world was performed - - public: - void CreateE3D(std::string const &dir = "", bool dyn = false); - void CabChange(TDynamicObject *old, TDynamicObject *now); - // handles vehicle change flag - void ChangeDynamic(); + bool m_init { false }; // indicates whether initial update of the world was performed + GLFWwindow *window; }; //--------------------------------------------------------------------------- diff --git a/sound.cpp b/sound.cpp index bd3f4ae7..be90f6e2 100644 --- a/sound.cpp +++ b/sound.cpp @@ -268,6 +268,18 @@ sound_source::deserialize_soundset( cParser &Input ) { } } +// copies list of sounds from provided source +sound_source & +sound_source::copy_sounds( sound_source const &Source ) { + + m_sounds = Source.m_sounds; + m_soundchunks = Source.m_soundchunks; + m_soundchunksempty = Source.m_soundchunksempty; + // NOTE: should probably zero the .playing fields here as precaution + // TODO: add this if we ever start copying sounds from active sources + return *this; +} + // issues contextual play commands for the audio renderer void sound_source::play( int const Flags ) { diff --git a/sound.h b/sound.h index 96fc8935..b1590c4b 100644 --- a/sound.h +++ b/sound.h @@ -58,6 +58,9 @@ public: deserialize( cParser &Input, sound_type const Legacytype, int const Legacyparameters = 0 ); sound_source & deserialize( std::string const &Input, sound_type const Legacytype, int const Legacyparameters = 0 ); + // copies list of sounds from provided source + sound_source & + copy_sounds( sound_source const &Source ); // issues contextual play commands for the audio renderer void play( int const Flags = 0 ); diff --git a/version.h b/version.h index 3a50be50..fc5a435c 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 17 -#define VERSION_MINOR 1222 +#define VERSION_MINOR 1224 #define VERSION_REVISION 0