mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 07:49:19 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
711
DynObj.cpp
711
DynObj.cpp
@@ -72,8 +72,7 @@ void TAnimPant::AKP_4E()
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
int TAnim::TypeSet(int i, int fl)
|
||||
{ // ustawienie typu animacji i zależnej od
|
||||
// niego ilości animowanych submodeli
|
||||
{ // ustawienie typu animacji i zależnej od niego ilości animowanych submodeli
|
||||
fMaxDist = -1.0; // normalnie nie pokazywać
|
||||
switch (i)
|
||||
{ // maska 0x000F: ile używa wskaźników na submodele (0 gdy jeden,
|
||||
@@ -106,16 +105,19 @@ int TAnim::TypeSet(int i, int fl)
|
||||
case 6:
|
||||
iFlags = 0x068;
|
||||
break; // 6-tłok i rozrząd - 8 submodeli
|
||||
case 7:
|
||||
iFlags = 0x070;
|
||||
break; // doorstep
|
||||
case 8:
|
||||
iFlags = 0x080;
|
||||
break; // mirror
|
||||
default:
|
||||
iFlags = 0;
|
||||
}
|
||||
yUpdate = nullptr;
|
||||
return iFlags & 15; // ile wskaźników rezerwować dla danego typu animacji
|
||||
};
|
||||
TAnim::TAnim()
|
||||
{ // potrzebne to w ogóle?
|
||||
iFlags = -1; // nieznany typ - destruktor nic nie usuwa
|
||||
};
|
||||
|
||||
TAnim::~TAnim()
|
||||
{ // usuwanie animacji
|
||||
switch (iFlags & 0xF0)
|
||||
@@ -126,13 +128,15 @@ TAnim::~TAnim()
|
||||
case 0x50: // 5-pantograf
|
||||
delete fParamPants;
|
||||
break;
|
||||
case 0x60: // 6-tłok i rozrząd
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
/*
|
||||
void TAnim::Parovoz(){
|
||||
// animowanie tłoka i rozrządu parowozu
|
||||
};
|
||||
*/
|
||||
//---------------------------------------------------------------------------
|
||||
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
|
||||
{ // szukanie skrajnego połączonego pojazdu w pociagu
|
||||
@@ -402,11 +406,6 @@ void TDynamicObject::UpdateBoogie(TAnim *pAnim)
|
||||
|
||||
void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
||||
{ // animacja drzwi - przesuw
|
||||
// WriteLog("Dla drzwi nr:", i);
|
||||
// WriteLog("Wspolczynnik", DoorSpeedFactor[i]);
|
||||
// Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia
|
||||
// w efekcie drzwi otwierane na zewnątrz będą odlatywac dowolnie daleko :)
|
||||
// ograniczyłem zakres ruchu funkcją max
|
||||
if (pAnim->smAnimated) {
|
||||
|
||||
if( pAnim->iNumber & 1 ) {
|
||||
@@ -429,9 +428,7 @@ void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
||||
void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
||||
{ // animacja drzwi - obrót
|
||||
if (pAnim->smAnimated)
|
||||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
||||
// albo dwójłomne (trzeba kombinowac
|
||||
// submodelami i ShiftL=90,R=180)
|
||||
{
|
||||
if (pAnim->iNumber & 1)
|
||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveR);
|
||||
else
|
||||
@@ -442,9 +439,7 @@ void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
||||
void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
||||
{ // animacja drzwi - obrót
|
||||
if (pAnim->smAnimated)
|
||||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
||||
// albo dwójłomne (trzeba kombinowac
|
||||
// submodelami i ShiftL=90,R=180)
|
||||
{
|
||||
if (pAnim->iNumber & 1)
|
||||
{
|
||||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveR);
|
||||
@@ -460,7 +455,6 @@ void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
||||
else
|
||||
{
|
||||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveL);
|
||||
// SubModel->SetRotate(float3(0,1,0),fValue*360.0);
|
||||
TSubModel *sm = pAnim->smAnimated->ChildGet(); // skrzydło mniejsze
|
||||
if (sm)
|
||||
{
|
||||
@@ -473,6 +467,35 @@ void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
||||
}
|
||||
};
|
||||
|
||||
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
|
||||
{ // animacja drzwi - odskokprzesuw
|
||||
if (pAnim->smAnimated) {
|
||||
|
||||
if( pAnim->iNumber & 1 ) {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3 {
|
||||
std::min(
|
||||
dDoorMoveR * 2,
|
||||
MoverParameters->DoorMaxPlugShift ),
|
||||
0.0,
|
||||
std::max(
|
||||
0.0,
|
||||
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
||||
}
|
||||
else {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3 {
|
||||
std::min(
|
||||
dDoorMoveL * 2,
|
||||
MoverParameters->DoorMaxPlugShift ),
|
||||
0.0,
|
||||
std::max(
|
||||
0.0,
|
||||
dDoorMoveL - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||||
{ // animacja pantografu - 4 obracane ramiona, ślizg piąty
|
||||
float a, b, c;
|
||||
@@ -489,37 +512,66 @@ void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
||||
if (pAnim->smElement[4])
|
||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg
|
||||
};
|
||||
}
|
||||
|
||||
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
|
||||
{ // animacja drzwi - odskokprzesuw
|
||||
if (pAnim->smAnimated) {
|
||||
// doorstep animation, shift
|
||||
void TDynamicObject::UpdatePlatformTranslate( TAnim *pAnim ) {
|
||||
|
||||
if( pAnim->iNumber & 1 ) {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3 {
|
||||
std::min(
|
||||
dDoorMoveR * 2,
|
||||
MoverParameters->DoorMaxPlugShift ),
|
||||
0.0,
|
||||
std::max(
|
||||
0.0,
|
||||
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5 ) } );
|
||||
}
|
||||
else {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3 {
|
||||
std::min(
|
||||
dDoorMoveL * 2,
|
||||
MoverParameters->DoorMaxPlugShift ),
|
||||
0.0,
|
||||
std::max(
|
||||
0.0,
|
||||
dDoorMoveL - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
||||
}
|
||||
if( pAnim->smAnimated == nullptr ) { return; }
|
||||
|
||||
if( pAnim->iNumber & 1 ) {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3{
|
||||
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveR ),
|
||||
0.0,
|
||||
0.0 } );
|
||||
}
|
||||
};
|
||||
else {
|
||||
pAnim->smAnimated->SetTranslate(
|
||||
Math3D::vector3{
|
||||
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveL ),
|
||||
0.0,
|
||||
0.0 } );
|
||||
}
|
||||
}
|
||||
|
||||
// doorstep animation, rotate
|
||||
void TDynamicObject::UpdatePlatformRotate( TAnim *pAnim ) {
|
||||
|
||||
if( pAnim->smAnimated == nullptr ) { return; }
|
||||
|
||||
if( pAnim->iNumber & 1 )
|
||||
pAnim->smAnimated->SetRotate(
|
||||
float3( 0, 1, 0 ),
|
||||
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveR ) );
|
||||
else
|
||||
pAnim->smAnimated->SetRotate(
|
||||
float3( 0, 1, 0 ),
|
||||
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveL ) );
|
||||
}
|
||||
|
||||
// mirror animation, rotate
|
||||
void TDynamicObject::UpdateMirror( TAnim *pAnim ) {
|
||||
|
||||
if( pAnim->smAnimated == nullptr ) { return; }
|
||||
|
||||
// only animate the mirror if it's located on the same end of the vehicle as the active cab
|
||||
auto const isactive { (
|
||||
MoverParameters->ActiveCab > 0 ? ( ( pAnim->iNumber >> 4 ) == side::front ? 1.0 : 0.0 ) :
|
||||
MoverParameters->ActiveCab < 0 ? ( ( pAnim->iNumber >> 4 ) == side::rear ? 1.0 : 0.0 ) :
|
||||
0.0 ) };
|
||||
|
||||
if( pAnim->iNumber & 1 )
|
||||
pAnim->smAnimated->SetRotate(
|
||||
float3( 0, 1, 0 ),
|
||||
interpolate( 0.0, MoverParameters->MirrorMaxShift, dMirrorMoveR * isactive ) );
|
||||
else
|
||||
pAnim->smAnimated->SetRotate(
|
||||
float3( 0, 1, 0 ),
|
||||
interpolate( 0.0, MoverParameters->MirrorMaxShift, dMirrorMoveL * isactive ) );
|
||||
}
|
||||
|
||||
/*
|
||||
void TDynamicObject::UpdateLeverDouble(TAnim *pAnim)
|
||||
{ // animacja gałki zależna od double
|
||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fDoubleBase);
|
||||
@@ -539,7 +591,7 @@ void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
|
||||
// pAnim->fParam[0]; - dodać lepkość
|
||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fParam[*pAnim->iIntBase]);
|
||||
};
|
||||
|
||||
*/
|
||||
// sets light levels for registered interior sections
|
||||
void
|
||||
TDynamicObject::toggle_lights() {
|
||||
@@ -588,10 +640,14 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
|
||||
if (ObjSqrDist < ( 400 * 400 ) ) // gdy bliżej niż 400m
|
||||
{
|
||||
for (int i = 0; i < iAnimations; ++i) // wykonanie kolejnych animacji
|
||||
if (ObjSqrDist < pAnimations[ i ].fMaxDist)
|
||||
if (pAnimations[ i ].yUpdate) // jeśli zdefiniowana funkcja
|
||||
pAnimations[ i ].yUpdate( &pAnimations[ i ] ); // aktualizacja animacji (położenia submodeli
|
||||
for( auto &animation : pAnimations ) {
|
||||
// wykonanie kolejnych animacji
|
||||
if( ( ObjSqrDist < animation.fMaxDist )
|
||||
&& ( animation.yUpdate ) ) {
|
||||
// jeśli zdefiniowana funkcja aktualizacja animacji (położenia submodeli
|
||||
animation.yUpdate( &animation );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( mdModel != nullptr )
|
||||
&& ( ObjSqrDist < ( 50 * 50 ) ) ) {
|
||||
@@ -1657,13 +1713,6 @@ TDynamicObject::TDynamicObject() {
|
||||
// w MMD)
|
||||
// ustawienie liczby modeli animowanych podczas konstruowania obiektu a nie na 0
|
||||
// prowadzi prosto do wysypów jeśli źle zdefiniowane mmd
|
||||
iAnimType[ANIM_WHEELS] = 0; // 0-osie (8)
|
||||
iAnimType[ANIM_DOORS] = 0; // 1-drzwi (8)
|
||||
iAnimType[ANIM_LEVERS] = 0; // 2-wahacze (4) - np. nogi konia
|
||||
iAnimType[ANIM_BUFFERS] = 0; // 3-zderzaki (4)
|
||||
iAnimType[ANIM_BOOGIES] = 0; // 4-wózki (2)
|
||||
iAnimType[ANIM_PANTS] = 0; // 5-pantografy (2)
|
||||
iAnimType[ANIM_STEAMS] = 0; // 6-tłoki (napęd parowozu)
|
||||
iAnimations = 0; // na razie nie ma żadnego
|
||||
pAnimated = NULL;
|
||||
fShade = 0.0; // standardowe oświetlenie na starcie
|
||||
@@ -1977,7 +2026,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
}
|
||||
if( true == setambient ) {
|
||||
// TODO: pull ambient temperature from environment data
|
||||
MoverParameters->dizel_HeatSet( 15.f );
|
||||
MoverParameters->dizel_HeatSet( Global.AirTemperature );
|
||||
}
|
||||
} // temperature
|
||||
/* else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy
|
||||
@@ -3588,21 +3637,85 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||
dDoorMoveL += dt1 * MoverParameters->DoorOpenSpeed;
|
||||
dDoorMoveL = std::min( dDoorMoveL, MoverParameters->DoorMaxShiftL );
|
||||
DoorDelayL = 0.f;
|
||||
}
|
||||
if( ( dDoorMoveL > 0 )
|
||||
if( ( dDoorMoveL > 0.0 )
|
||||
&& ( false == MoverParameters->DoorLeftOpened ) ) {
|
||||
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||
dDoorMoveL = std::max( dDoorMoveL, 0.0 );
|
||||
DoorDelayL += dt1;
|
||||
if( DoorDelayL > MoverParameters->DoorCloseDelay ) {
|
||||
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||
dDoorMoveL = std::max( dDoorMoveL, 0.0 );
|
||||
}
|
||||
}
|
||||
if( ( dDoorMoveR < MoverParameters->DoorMaxShiftR )
|
||||
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||
dDoorMoveR += dt1 * MoverParameters->DoorOpenSpeed;
|
||||
dDoorMoveR = std::min( dDoorMoveR, MoverParameters->DoorMaxShiftR );
|
||||
}
|
||||
if( ( dDoorMoveR > 0 )
|
||||
DoorDelayR = 0.f;
|
||||
}
|
||||
if( ( dDoorMoveR > 0.0 )
|
||||
&& ( false == MoverParameters->DoorRightOpened ) ) {
|
||||
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||
dDoorMoveR = std::max( dDoorMoveR, 0.0 );
|
||||
DoorDelayR += dt1;
|
||||
if( DoorDelayR > MoverParameters->DoorCloseDelay ) {
|
||||
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||
dDoorMoveR = std::max( dDoorMoveR, 0.0 );
|
||||
}
|
||||
}
|
||||
// doorsteps
|
||||
if( ( dDoorstepMoveL < 1.0 )
|
||||
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||
dDoorstepMoveL = std::min(
|
||||
1.0,
|
||||
dDoorstepMoveL + MoverParameters->PlatformSpeed * dt1 );
|
||||
}
|
||||
if( ( dDoorstepMoveL > 0.0 )
|
||||
&& ( false == MoverParameters->DoorLeftOpened )
|
||||
&& ( DoorDelayL > MoverParameters->DoorCloseDelay ) ) {
|
||||
dDoorstepMoveL = std::max(
|
||||
0.0,
|
||||
dDoorstepMoveL - MoverParameters->PlatformSpeed * dt1 );
|
||||
}
|
||||
if( ( dDoorstepMoveR < 1.0 )
|
||||
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||
dDoorstepMoveR = std::min(
|
||||
1.0,
|
||||
dDoorstepMoveR + MoverParameters->PlatformSpeed * dt1 );
|
||||
}
|
||||
if( ( dDoorstepMoveR > 0.0 )
|
||||
&& ( false == MoverParameters->DoorRightOpened )
|
||||
&& ( DoorDelayR > MoverParameters->DoorCloseDelay ) ) {
|
||||
dDoorstepMoveR = std::max(
|
||||
0.0,
|
||||
dDoorstepMoveR - MoverParameters->PlatformSpeed * dt1 );
|
||||
}
|
||||
// mirrors
|
||||
if( MoverParameters->Vel > 5.0 ) {
|
||||
// automatically fold mirrors when above velocity threshold
|
||||
if( dMirrorMoveL > 0.0 ) {
|
||||
dMirrorMoveL = std::max(
|
||||
0.0,
|
||||
dMirrorMoveL - 1.0 * dt1 );
|
||||
}
|
||||
if( dMirrorMoveR > 0.0 ) {
|
||||
dMirrorMoveR = std::max(
|
||||
0.0,
|
||||
dMirrorMoveR - 1.0 * dt1 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// unfold mirror on the side with open doors, if not moving too fast
|
||||
if( ( dMirrorMoveL < 1.0 )
|
||||
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||
dMirrorMoveL = std::min(
|
||||
1.0,
|
||||
dMirrorMoveL + 1.0 * dt1 );
|
||||
}
|
||||
if( ( dMirrorMoveR < 1.0 )
|
||||
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||
dMirrorMoveR = std::min(
|
||||
1.0,
|
||||
dMirrorMoveR + 1.0 * dt1 );
|
||||
}
|
||||
}
|
||||
|
||||
// compartment lights
|
||||
@@ -3770,14 +3883,40 @@ void TDynamicObject::RenderSounds() {
|
||||
|
||||
|
||||
// brake system and braking sounds:
|
||||
|
||||
// brake cylinder piston
|
||||
auto const brakepressureratio { std::max( 0.0, MoverParameters->BrakePress ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) };
|
||||
if( m_lastbrakepressure != -1.f ) {
|
||||
auto const quantizedratio { static_cast<int>( 15 * brakepressureratio ) };
|
||||
auto const lastbrakepressureratio { std::max( 0.f, m_lastbrakepressure ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) };
|
||||
auto const quantizedratiochange { quantizedratio - static_cast<int>( 15 * lastbrakepressureratio ) };
|
||||
if( quantizedratiochange > 0 ) {
|
||||
m_brakecylinderpistonadvance
|
||||
.pitch(
|
||||
true == m_brakecylinderpistonadvance.is_combined() ?
|
||||
quantizedratio * 0.01f :
|
||||
m_brakecylinderpistonadvance.m_frequencyoffset + m_brakecylinderpistonadvance.m_frequencyfactor * 1.f )
|
||||
.play();
|
||||
}
|
||||
else if( quantizedratiochange < 0 ) {
|
||||
m_brakecylinderpistonrecede
|
||||
.pitch(
|
||||
true == m_brakecylinderpistonrecede.is_combined() ?
|
||||
quantizedratio * 0.01f :
|
||||
m_brakecylinderpistonrecede.m_frequencyoffset + m_brakecylinderpistonrecede.m_frequencyfactor * 1.f )
|
||||
.play();
|
||||
}
|
||||
}
|
||||
|
||||
// air release
|
||||
if( m_lastbrakepressure != -1.f ) {
|
||||
// calculate rate of pressure drop in brake cylinder, once it's been initialized
|
||||
auto const brakepressuredifference{ m_lastbrakepressure - MoverParameters->BrakePress };
|
||||
m_brakepressurechange = interpolate<float>( m_brakepressurechange, brakepressuredifference / dt, 0.005f );
|
||||
}
|
||||
m_lastbrakepressure = MoverParameters->BrakePress;
|
||||
// ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the leak rate
|
||||
volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * ( std::max( 0.0, MoverParameters->BrakePress ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) ) );
|
||||
// ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the air release rate
|
||||
volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * brakepressureratio );
|
||||
if( volume > 0.075f ) {
|
||||
rsUnbrake
|
||||
.gain( volume )
|
||||
@@ -3805,6 +3944,7 @@ void TDynamicObject::RenderSounds() {
|
||||
sReleaser.stop();
|
||||
}
|
||||
|
||||
// slipping wheels
|
||||
if( MoverParameters->SlippingWheels ) {
|
||||
|
||||
if( ( MoverParameters->UnitBrakeForce > 100.0 )
|
||||
@@ -3828,6 +3968,7 @@ void TDynamicObject::RenderSounds() {
|
||||
sSand.stop();
|
||||
}
|
||||
|
||||
// brakes
|
||||
auto brakeforceratio{ 0.0 };
|
||||
if( //( false == mvOccupied->SlippingWheels ) &&
|
||||
( MoverParameters->UnitBrakeForce > 10.0 )
|
||||
@@ -3888,7 +4029,14 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
// NBMX sygnal odjazdu
|
||||
if( MoverParameters->DoorClosureWarning ) {
|
||||
if( MoverParameters->DepartureSignal ) {
|
||||
if( ( MoverParameters->DepartureSignal )
|
||||
/*
|
||||
|| ( ( MoverParameters->DoorCloseCtrl = control::autonomous )
|
||||
&& ( ( ( false == MoverParameters->DoorLeftOpened ) && ( dDoorMoveL > 0.0 ) )
|
||||
|| ( ( false == MoverParameters->DoorRightOpened ) && ( dDoorMoveR > 0.0 ) ) ) )
|
||||
*/
|
||||
) {
|
||||
// for the autonomous doors play the warning automatically whenever a door is closing
|
||||
// MC: pod warunkiem ze jest zdefiniowane w chk
|
||||
sDepartureSignal.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
@@ -3897,47 +4045,96 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
}
|
||||
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
||||
if( ( true == MoverParameters->DoorLeftOpened )
|
||||
&& ( dDoorMoveL < MoverParameters->DoorMaxShiftL ) ) {
|
||||
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||
door.rsDoorClose.stop();
|
||||
if( true == MoverParameters->DoorLeftOpened ) {
|
||||
// open left door
|
||||
// door sounds
|
||||
if( dDoorMoveL < MoverParameters->DoorMaxShiftL ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||
door.rsDoorClose.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// doorstep sounds
|
||||
if( dDoorstepMoveL < 1.0 ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.step_close.offset().x > 0.f ) {
|
||||
door.step_open.play( sound_flags::exclusive );
|
||||
door.step_close.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( false == MoverParameters->DoorLeftOpened )
|
||||
&& ( dDoorMoveL > 0.01 ) ) {
|
||||
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorClose.play( sound_flags::exclusive );
|
||||
door.rsDoorOpen.stop();
|
||||
if( false == MoverParameters->DoorLeftOpened ) {
|
||||
// close left door
|
||||
// door sounds can start playing before the door begins moving
|
||||
if( dDoorMoveL > 0.0 ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorClose.play( sound_flags::exclusive );
|
||||
door.rsDoorOpen.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// doorstep sounds are played only when the doorstep is moving
|
||||
if( ( dDoorstepMoveL > 0.0 )
|
||||
&& ( dDoorstepMoveL < 1.0 ) ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.step_close.offset().x > 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.step_close.play( sound_flags::exclusive );
|
||||
door.step_open.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( true == MoverParameters->DoorRightOpened )
|
||||
&& ( dDoorMoveR < MoverParameters->DoorMaxShiftR ) ) {
|
||||
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||
door.rsDoorClose.stop();
|
||||
if( true == MoverParameters->DoorRightOpened ) {
|
||||
// open right door
|
||||
// door sounds
|
||||
if( dDoorMoveR < MoverParameters->DoorMaxShiftR ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||
// determine right side doors from their offset
|
||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||
door.rsDoorClose.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// doorstep sounds
|
||||
if( dDoorstepMoveR < 1.0 ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.step_close.offset().x < 0.f ) {
|
||||
door.step_open.play( sound_flags::exclusive );
|
||||
door.step_close.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( false == MoverParameters->DoorRightOpened )
|
||||
&& ( dDoorMoveR > 0.01 ) ) {
|
||||
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorClose.play( sound_flags::exclusive );
|
||||
door.rsDoorOpen.stop();
|
||||
if( false == MoverParameters->DoorRightOpened ) {
|
||||
// close right door
|
||||
// door sounds can start playing before the door begins moving
|
||||
if( dDoorMoveR > 0.0 ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.rsDoorClose.play( sound_flags::exclusive );
|
||||
door.rsDoorOpen.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// doorstep sounds are played only when the doorstep is moving
|
||||
if( ( dDoorstepMoveR > 0.0 )
|
||||
&& ( dDoorstepMoveR < 1.0 ) ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
if( door.step_close.offset().x < 0.f ) {
|
||||
// determine left side doors from their offset
|
||||
door.step_close.play( sound_flags::exclusive );
|
||||
door.step_open.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3954,6 +4151,12 @@ void TDynamicObject::RenderSounds() {
|
||||
else {
|
||||
sHorn2.stop();
|
||||
}
|
||||
if( TestFlag( MoverParameters->WarningSignal, 4 ) ) {
|
||||
sHorn3.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else {
|
||||
sHorn3.stop();
|
||||
}
|
||||
// szum w czasie jazdy
|
||||
if( ( GetVelocity() > 0.5 )
|
||||
&& ( false == m_bogiesounds.empty() )
|
||||
@@ -4340,64 +4543,39 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
{ // kolejne liczby to ilość animacj, -1 to znacznik końca
|
||||
parser.getTokens( 1, false );
|
||||
parser >> ile; // ilość danego typu animacji
|
||||
// if (co==ANIM_PANTS)
|
||||
// if (!Global.bLoadTraction)
|
||||
// if (!DebugModeFlag) //w debugmode pantografy mają "niby działać"
|
||||
// ile=0; //wyłączenie animacji pantografów
|
||||
if (co < ANIM_TYPES)
|
||||
if (ile >= 0)
|
||||
{
|
||||
iAnimType[co] = ile; // zapamiętanie
|
||||
iAnimations += ile; // ogólna ilość animacji
|
||||
}
|
||||
if (ile >= 0)
|
||||
{
|
||||
iAnimType[co] = ile; // zapamiętanie
|
||||
iAnimations += ile; // ogólna ilość animacji
|
||||
}
|
||||
else {
|
||||
iAnimType[co] = 0;
|
||||
}
|
||||
++co;
|
||||
} while (ile >= 0); //-1 to znacznik końca
|
||||
} while ( (ile >= 0) && (co < ANIM_TYPES) ); //-1 to znacznik końca
|
||||
|
||||
while( co < ANIM_TYPES ) {
|
||||
iAnimType[ co++ ] = 0; // zerowanie pozostałych
|
||||
}
|
||||
parser.getTokens(); parser >> token; // NOTE: should this be here? seems at best superfluous
|
||||
}
|
||||
// WriteLog("Total animations: "+AnsiString(iAnimations));
|
||||
}
|
||||
|
||||
if( true == pAnimations.empty() ) {
|
||||
// Ra: tworzenie tabeli animacji, jeśli jeszcze nie było
|
||||
/*
|
||||
// disabled as default animation amounts are no longer supported
|
||||
if( !iAnimations ) {
|
||||
// jeśli nie podano jawnie, ile ma być animacji
|
||||
iAnimations = 28; // tyle było kiedyś w każdym pojeździe (2 wiązary wypadły)
|
||||
}
|
||||
*/
|
||||
/* //pojazd może mieć pantograf do innych celów niż napęd
|
||||
if (MoverParameters->EnginePowerSource.SourceType!=CurrentCollector)
|
||||
{//nie będzie pantografów, to się trochę uprości
|
||||
iAnimations-=iAnimType[ANIM_PANTS]; //domyślnie były 2 pantografy
|
||||
iAnimType[ANIM_PANTS]=0;
|
||||
}
|
||||
*/
|
||||
pAnimations.resize( iAnimations );
|
||||
int i, j, k = 0, sm = 0;
|
||||
for (j = 0; j < ANIM_TYPES; ++j)
|
||||
for (i = 0; i < iAnimType[j]; ++i)
|
||||
pAnimations.resize( iAnimations );
|
||||
int i, j, k = 0, sm = 0;
|
||||
for (j = 0; j < ANIM_TYPES; ++j)
|
||||
for (i = 0; i < iAnimType[j]; ++i)
|
||||
{
|
||||
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
||||
if (!pants)
|
||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
if (sm) // o ile są bardziej złożone animacje
|
||||
{
|
||||
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
||||
if (!pants)
|
||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||||
for (k = 0; k < iAnimations; ++k)
|
||||
pAnimations[k].smElement = pAnimated + pAnimations[k].iShift; // przydzielenie wskaźnika do tabelki
|
||||
}
|
||||
if (sm) // o ile są bardziej złożone animacje
|
||||
{
|
||||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||||
for (k = 0; k < iAnimations; ++k)
|
||||
pAnimations[k].smElement = pAnimated + pAnimations[k].iShift; // przydzielenie wskaźnika do tabelki
|
||||
}
|
||||
}
|
||||
|
||||
if(token == "lowpolyinterior:") {
|
||||
else if(token == "lowpolyinterior:") {
|
||||
// ABu: wnetrze lowpoly
|
||||
parser.getTokens();
|
||||
parser >> asModel;
|
||||
@@ -4405,10 +4583,9 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
||||
// Global.asCurrentTexturePath=AnsiString(szTexturePath); //kiedyś uproszczone wnętrze mieszało tekstury nieba
|
||||
}
|
||||
|
||||
if( token == "brakemode:" ) {
|
||||
else if( token == "brakemode:" ) {
|
||||
// Ra 15-01: gałka nastawy hamulca
|
||||
parser.getTokens();
|
||||
parser >> asAnimName;
|
||||
@@ -4416,7 +4593,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
||||
}
|
||||
|
||||
if( token == "loadmode:" ) {
|
||||
else if( token == "loadmode:" ) {
|
||||
// Ra 15-01: gałka nastawy hamulca
|
||||
parser.getTokens();
|
||||
parser >> asAnimName;
|
||||
@@ -4486,7 +4663,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
// Ra: pantografy po nowemu mają literki i numerki
|
||||
}
|
||||
// Pantografy - Winger 160204
|
||||
if( token == "animpantrd1prefix:" ) {
|
||||
else if( token == "animpantrd1prefix:" ) {
|
||||
// prefiks ramion dolnych 1
|
||||
parser.getTokens(); parser >> token;
|
||||
float4x4 m; // macierz do wyliczenia pozycji i wektora ruchu pantografu
|
||||
@@ -4653,6 +4830,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "pantfactors:" ) {
|
||||
// Winger 010304:
|
||||
// parametry pantografow
|
||||
@@ -4790,23 +4968,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
parser >> fWahaczeAmp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (str == AnsiString("engineer:"))
|
||||
{ // nazwa submodelu maszynisty
|
||||
str = Parser->GetNextSymbol();
|
||||
smMechanik0 = mdModel->GetFromName(str.c_str());
|
||||
if (!smMechanik0)
|
||||
{ // jak nie ma bez numerka, to może jest z
|
||||
// numerkiem?
|
||||
smMechanik0 = mdModel->GetFromName(AnsiString(str + "1").c_str());
|
||||
smMechanik1 = mdModel->GetFromName(AnsiString(str + "2").c_str());
|
||||
}
|
||||
// aby dało się go obracać, musi mieć włączoną animację w T3D!
|
||||
// if (!smMechanik1) //jeśli drugiego nie ma
|
||||
// if (smMechanik0) //a jest pierwszy
|
||||
// smMechanik0->WillBeAnimated(); //to będziemy go obracać
|
||||
}
|
||||
*/
|
||||
|
||||
else if( token == "animdoorprefix:" ) {
|
||||
// nazwa animowanych drzwi
|
||||
@@ -4841,9 +5002,80 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste
|
||||
pAnimations[i + j].fMaxDist = 300 * 300; // drzwi to z daleka widać
|
||||
/*
|
||||
// NOTE: no longer used
|
||||
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||
// Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "animstepprefix:" ) {
|
||||
// animated doorstep submodel name prefix
|
||||
int i, j;
|
||||
parser.getTokens(1, false); parser >> token;
|
||||
for (i = 0, j = 0; i < ANIM_DOORSTEPS; ++i)
|
||||
j += iAnimType[i]; // zliczanie wcześniejszych animacji
|
||||
for (i = 0; i < iAnimType[ANIM_DOORSTEPS]; ++i) // liczba drzwi
|
||||
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
|
||||
// ustalenie submodelu
|
||||
asAnimName = token + std::to_string(i + 1);
|
||||
pAnimations[i + j].smAnimated = mdModel->GetFromName(asAnimName);
|
||||
if (pAnimations[i + j].smAnimated)
|
||||
{ //++iAnimatedDoors;
|
||||
pAnimations[i + j].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||
switch (MoverParameters->PlatformOpenMethod)
|
||||
{ // od razu zapinamy potrzebny typ animacji
|
||||
case 1: // shift
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdatePlatformTranslate, this, std::placeholders::_1 );
|
||||
break;
|
||||
case 2: // rotate
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdatePlatformRotate, this, std::placeholders::_1 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste
|
||||
pAnimations[i + j].fMaxDist = 150 * 150; // drzwi to z daleka widać
|
||||
/*
|
||||
// NOTE: no longer used
|
||||
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "animmirrorprefix:" ) {
|
||||
// animated mirror submodel name prefix
|
||||
int i, j;
|
||||
parser.getTokens( 1, false ); parser >> token;
|
||||
for( i = 0, j = 0; i < ANIM_MIRRORS; ++i )
|
||||
j += iAnimType[ i ]; // zliczanie wcześniejszych animacji
|
||||
for( i = 0; i < iAnimType[ ANIM_MIRRORS ]; ++i ) // liczba drzwi
|
||||
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
|
||||
// ustalenie submodelu
|
||||
asAnimName = token + std::to_string( i + 1 );
|
||||
pAnimations[ i + j ].smAnimated = mdModel->GetFromName( asAnimName );
|
||||
if( pAnimations[ i + j ].smAnimated ) {
|
||||
pAnimations[ i + j ].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||
// od razu zapinamy potrzebny typ animacji
|
||||
auto const offset { pAnimations[ i + j ].smAnimated->offset() };
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateMirror, this, std::placeholders::_1 );
|
||||
// we don't expect more than 2-4 mirrors, so it should be safe to store submodel location (front/rear) in the higher bits
|
||||
// parzyste działają inaczej niż nieparzyste
|
||||
pAnimations[ i + j ].iNumber =
|
||||
( ( pAnimations[ i + j ].smAnimated->offset().z > 0 ?
|
||||
side::front :
|
||||
side::rear ) << 4 )
|
||||
+ i;
|
||||
pAnimations[ i + j ].fMaxDist = 150 * 150; // drzwi to z daleka widać
|
||||
/*
|
||||
// NOTE: no longer used
|
||||
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4984,6 +5216,18 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
rsPisk.m_amplitudeoffset *= ( 105.f - Random( 10.f ) ) / 100.f;
|
||||
}
|
||||
|
||||
else if( token == "brakecylinderinc:" ) {
|
||||
// brake cylinder pressure increase sounds
|
||||
m_brakecylinderpistonadvance.deserialize( parser, sound_type::single );
|
||||
m_brakecylinderpistonadvance.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "brakecylinderdec:" ) {
|
||||
// brake cylinder pressure decrease sounds
|
||||
m_brakecylinderpistonrecede.deserialize( parser, sound_type::single );
|
||||
m_brakecylinderpistonrecede.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "brakeacc:" ) {
|
||||
// plik z przyspieszaczem (upust po zlapaniu hamowania)
|
||||
sBrakeAcc.deserialize( parser, sound_type::single );
|
||||
@@ -5019,12 +5263,17 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
// pliki z trabieniem wysokoton.
|
||||
sHorn2.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||
sHorn2.owner( this );
|
||||
|
||||
// TBD, TODO: move horn selection to ai config file
|
||||
if( iHornWarning ) {
|
||||
iHornWarning = 2; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "horn3:" ) {
|
||||
sHorn3.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||
sHorn3.owner( this );
|
||||
}
|
||||
|
||||
else if( token == "departuresignal:" ) {
|
||||
// pliki z sygnalem odjazdu
|
||||
sDepartureSignal.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||
@@ -5067,6 +5316,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
// pliki z turbogeneratorem
|
||||
m_powertrainsounds.engine_turbo.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||
m_powertrainsounds.engine_turbo.owner( this );
|
||||
m_powertrainsounds.engine_turbo.gain( 0 );
|
||||
}
|
||||
|
||||
else if( token == "small-compressor:" ) {
|
||||
@@ -5076,29 +5326,53 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
|
||||
else if( token == "dooropen:" ) {
|
||||
sound_source doortemplate { sound_placement::general };
|
||||
doortemplate.deserialize( parser, sound_type::single );
|
||||
doortemplate.owner( this );
|
||||
sound_source soundtemplate { sound_placement::general };
|
||||
soundtemplate.deserialize( parser, sound_type::single );
|
||||
soundtemplate.owner( this );
|
||||
for( auto &door : m_doorsounds ) {
|
||||
// apply configuration to all defined doors, but preserve their individual offsets
|
||||
auto const dooroffset { door.rsDoorOpen.offset() };
|
||||
door.rsDoorOpen = doortemplate;
|
||||
door.rsDoorOpen = soundtemplate;
|
||||
door.rsDoorOpen.offset( dooroffset );
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "doorclose:" ) {
|
||||
sound_source doortemplate { sound_placement::general };
|
||||
doortemplate.deserialize( parser, sound_type::single );
|
||||
doortemplate.owner( this );
|
||||
sound_source soundtemplate { sound_placement::general };
|
||||
soundtemplate.deserialize( parser, sound_type::single );
|
||||
soundtemplate.owner( this );
|
||||
for( auto &door : m_doorsounds ) {
|
||||
// apply configuration to all defined doors, but preserve their individual offsets
|
||||
auto const dooroffset { door.rsDoorClose.offset() };
|
||||
door.rsDoorClose = doortemplate;
|
||||
door.rsDoorClose = soundtemplate;
|
||||
door.rsDoorClose.offset( dooroffset );
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "doorstepopen:" ) {
|
||||
sound_source soundtemplate { sound_placement::general };
|
||||
soundtemplate.deserialize( parser, sound_type::single );
|
||||
soundtemplate.owner( this );
|
||||
for( auto &door : m_doorsounds ) {
|
||||
// apply configuration to all defined doors, but preserve their individual offsets
|
||||
auto const dooroffset { door.step_open.offset() };
|
||||
door.step_open = soundtemplate;
|
||||
door.step_open.offset( dooroffset );
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "doorstepclose:" ) {
|
||||
sound_source soundtemplate { sound_placement::general };
|
||||
soundtemplate.deserialize( parser, sound_type::single );
|
||||
soundtemplate.owner( this );
|
||||
for( auto &door : m_doorsounds ) {
|
||||
// apply configuration to all defined doors, but preserve their individual offsets
|
||||
auto const dooroffset { door.step_close.offset() };
|
||||
door.step_close = soundtemplate;
|
||||
door.step_close.offset( dooroffset );
|
||||
}
|
||||
}
|
||||
|
||||
else if( token == "unloading:" ) {
|
||||
m_exchangesounds.unloading.deserialize( parser, sound_type::single );
|
||||
m_exchangesounds.unloading.owner( this );
|
||||
@@ -5178,6 +5452,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||
door.rsDoorClose.offset( location );
|
||||
door.rsDoorOpen.offset( location );
|
||||
door.step_close.offset( location );
|
||||
door.step_open.offset( location );
|
||||
m_doorsounds.emplace_back( door );
|
||||
}
|
||||
if( ( sides == "both" )
|
||||
@@ -5186,6 +5462,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
auto const location { glm::vec3 { MoverParameters->Dim.W * -0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||
door.rsDoorClose.offset( location );
|
||||
door.rsDoorOpen.offset( location );
|
||||
door.step_close.offset( location );
|
||||
door.step_open.offset( location );
|
||||
m_doorsounds.emplace_back( door );
|
||||
}
|
||||
}
|
||||
@@ -6413,19 +6691,9 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
||||
// Ra 2015-01: tylko tu przelicza sieć trakcyjną
|
||||
vehicle->Update( Deltatime, totaltime );
|
||||
}
|
||||
/*
|
||||
// TODO: re-implement
|
||||
if (TDynamicObject::bDynamicRemove)
|
||||
{ // jeśli jest coś do usunięcia z listy, to trzeba na końcu
|
||||
for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext)
|
||||
if ( false == Current->DynamicObject->bEnabled)
|
||||
{
|
||||
DynamicRemove(Current->DynamicObject); // usunięcie tego i podłączonych
|
||||
Current = nRootDynamic; // sprawdzanie listy od początku
|
||||
}
|
||||
TDynamicObject::bDynamicRemove = false; // na razie koniec
|
||||
}
|
||||
*/
|
||||
|
||||
// jeśli jest coś do usunięcia z listy, to trzeba na końcu
|
||||
erase_disabled();
|
||||
}
|
||||
|
||||
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||
@@ -6536,3 +6804,56 @@ vehicle_table::DynamicList( bool const Onlycontrolled ) const {
|
||||
// informacja o końcu listy
|
||||
multiplayer::WyslijString( "none", 6 );
|
||||
}
|
||||
|
||||
// maintenance; removes from tracks consists with vehicles marked as disabled
|
||||
bool
|
||||
vehicle_table::erase_disabled() {
|
||||
|
||||
if( false == TDynamicObject::bDynamicRemove ) { return false; }
|
||||
|
||||
// go through the list and retrieve vehicles scheduled for removal...
|
||||
type_sequence disabledvehicles;
|
||||
for( auto *vehicle : m_items ) {
|
||||
if( false == vehicle->bEnabled ) {
|
||||
disabledvehicles.emplace_back( vehicle );
|
||||
}
|
||||
}
|
||||
// ...now propagate removal flag through affected consists...
|
||||
for( auto *vehicle : disabledvehicles ) {
|
||||
TDynamicObject *coupledvehicle { vehicle };
|
||||
while( ( coupledvehicle = coupledvehicle->Next() ) != nullptr ) {
|
||||
coupledvehicle->bEnabled = false;
|
||||
}
|
||||
// (try to) run propagation in both directions, it's simpler than branching based on direction etc
|
||||
coupledvehicle = vehicle;
|
||||
while( ( coupledvehicle = coupledvehicle->Prev() ) != nullptr ) {
|
||||
coupledvehicle->bEnabled = false;
|
||||
}
|
||||
}
|
||||
// ...then actually remove all disabled vehicles...
|
||||
auto vehicleiter = std::begin( m_items );
|
||||
while( vehicleiter != std::end( m_items ) ) {
|
||||
|
||||
auto *vehicle { *vehicleiter };
|
||||
|
||||
if( true == vehicle->bEnabled ) {
|
||||
++vehicleiter;
|
||||
}
|
||||
else {
|
||||
if( vehicle->MyTrack != nullptr ) {
|
||||
vehicle->MyTrack->RemoveDynamicObject( vehicle );
|
||||
}
|
||||
// clear potential train binding
|
||||
Global.pWorld->TrainDelete( vehicle );
|
||||
// remove potential entries in the light array
|
||||
simulation::Lights.remove( vehicle );
|
||||
// finally get rid of the vehicle and its record themselves
|
||||
SafeDelete( vehicle );
|
||||
vehicleiter = m_items.erase( vehicleiter );
|
||||
}
|
||||
}
|
||||
// ...and call it a day
|
||||
TDynamicObject::bDynamicRemove = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user