mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 16:49:18 +02:00
build 210424. soundproofing enhancement, battery sound, heating command propagation, memory cell command retrieval logic enhancement, coupling mode logic enhancement, motor overload relay threshold cab control animation fix, cab control fallback sound activation fixes,
This commit is contained in:
117
Driver.cpp
117
Driver.cpp
@@ -1676,14 +1676,19 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo
|
|||||||
else if( Point.evEvent->is_command() ) {
|
else if( Point.evEvent->is_command() ) {
|
||||||
// jeśli prędkość jest zerowa, a komórka zawiera komendę
|
// jeśli prędkość jest zerowa, a komórka zawiera komendę
|
||||||
eSignNext = Point.evEvent; // dla informacji
|
eSignNext = Point.evEvent; // dla informacji
|
||||||
if( true == TestFlag( iDrivigFlags, moveStopHere ) ) {
|
// make sure the command isn't for someone else
|
||||||
// jeśli ma stać, dostaje komendę od razu
|
// TBD, TODO: revise this check for bank/loose_shunt; we might want to ignore obstacles with no owner in these modes
|
||||||
Command = TCommandType::cm_Command; // komenda z komórki, do wykonania po zatrzymaniu
|
if( Point.fDist < Obstacle.distance ) {
|
||||||
}
|
if( true == TestFlag( iDrivigFlags, moveStopHere ) ) {
|
||||||
else if( Point.fDist <= fMaxProximityDist ) {
|
// jeśli ma stać, dostaje komendę od razu
|
||||||
// jeśli ma dociągnąć, to niech dociąga
|
Command = TCommandType::cm_Command; // komenda z komórki, do wykonania po zatrzymaniu
|
||||||
// (moveStopCloser dotyczy dociągania do W4, nie semafora)
|
}
|
||||||
Command = TCommandType::cm_Command; // komenda z komórki, do wykonania po zatrzymaniu
|
// NOTE: human drivers are likely to stop wherever and expect things to still work, so we give them more leeway
|
||||||
|
else if( Point.fDist <= ( AIControllFlag ? fMaxProximityDist : std::max( 250.0, fMaxProximityDist ) ) ) {
|
||||||
|
// jeśli ma dociągnąć, to niech dociąga
|
||||||
|
// (moveStopCloser dotyczy dociągania do W4, nie semafora)
|
||||||
|
Command = TCommandType::cm_Command; // komenda z komórki, do wykonania po zatrzymaniu
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1928,9 +1933,13 @@ TController::~TController()
|
|||||||
// zamiana kodu rozkazu na opis
|
// zamiana kodu rozkazu na opis
|
||||||
std::string TController::Order2Str(TOrders Order) const {
|
std::string TController::Order2Str(TOrders Order) const {
|
||||||
|
|
||||||
if( Order & Change_direction ) {
|
if( ( ( Order & Change_direction ) != 0 )
|
||||||
|
&& ( Order != Change_direction ) ) {
|
||||||
// może być nałożona na inną i wtedy ma priorytet
|
// może być nałożona na inną i wtedy ma priorytet
|
||||||
return "Change_direction";
|
return
|
||||||
|
Order2Str( Change_direction )
|
||||||
|
+ " + "
|
||||||
|
+ Order2Str( static_cast<TOrders>( Order & ~Change_direction ) );
|
||||||
}
|
}
|
||||||
switch( Order ) {
|
switch( Order ) {
|
||||||
case Wait_for_orders: return "Wait_for_orders";
|
case Wait_for_orders: return "Wait_for_orders";
|
||||||
@@ -1953,11 +1962,15 @@ std::array<char, 64> orderbuffer;
|
|||||||
std::string TController::OrderCurrent() const
|
std::string TController::OrderCurrent() const
|
||||||
{ // pobranie aktualnego rozkazu celem wyświetlenia
|
{ // pobranie aktualnego rozkazu celem wyświetlenia
|
||||||
auto const order { OrderCurrentGet() };
|
auto const order { OrderCurrentGet() };
|
||||||
|
// generally prioritize direction change...
|
||||||
if( order & Change_direction ) {
|
if( order & Change_direction ) {
|
||||||
return locale::strings[ locale::string::driver_scenario_changedirection ];
|
// ...but not in the middle of coupling operation
|
||||||
|
if( false == TestFlag( iDrivigFlags, moveConnect ) ) {
|
||||||
|
return locale::strings[ locale::string::driver_scenario_changedirection ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( OrderList[ OrderPos ] ) {
|
switch( static_cast<TOrders>( order & ~Change_direction ) ) {
|
||||||
case Wait_for_orders: { return locale::strings[ locale::string::driver_scenario_waitfororders ]; }
|
case Wait_for_orders: { return locale::strings[ locale::string::driver_scenario_waitfororders ]; }
|
||||||
case Prepare_engine: { return locale::strings[ locale::string::driver_scenario_prepareengine ]; }
|
case Prepare_engine: { return locale::strings[ locale::string::driver_scenario_prepareengine ]; }
|
||||||
case Release_engine: { return locale::strings[ locale::string::driver_scenario_releaseengine ]; }
|
case Release_engine: { return locale::strings[ locale::string::driver_scenario_releaseengine ]; }
|
||||||
@@ -4927,17 +4940,20 @@ TController::PrepareDirection() {
|
|||||||
locale::string::driver_hint_directionbackward );
|
locale::string::driver_hint_directionbackward );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TController::JumpToNextOrder()
|
void TController::JumpToNextOrder( bool const Ignoremergedchangedirection )
|
||||||
{ // wykonanie kolejnej komendy z tablicy rozkazów
|
{ // wykonanie kolejnej komendy z tablicy rozkazów
|
||||||
if (OrderList[OrderPos] != Wait_for_orders)
|
if (OrderList[OrderPos] != Wait_for_orders)
|
||||||
{
|
{
|
||||||
if (OrderList[OrderPos] & Change_direction) // jeśli zmiana kierunku
|
if( ( ( OrderList[ OrderPos ] & Change_direction ) != 0 ) // jeśli zmiana kierunku
|
||||||
if (OrderList[OrderPos] != Change_direction) // ale nałożona na coś
|
&& ( OrderList[ OrderPos ] != Change_direction ) ) { // ale nałożona na coś
|
||||||
{
|
|
||||||
OrderList[OrderPos] = TOrders(OrderList[OrderPos] & ~Change_direction); // usunięcie zmiany kierunku z innej komendy
|
if( false == Ignoremergedchangedirection ) {
|
||||||
|
// usunięcie zmiany kierunku z innej komendy
|
||||||
|
OrderList[ OrderPos ] = TOrders( OrderList[ OrderPos ] & ~Change_direction );
|
||||||
OrderCheck();
|
OrderCheck();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OrderPos < maxorders - 1)
|
if (OrderPos < maxorders - 1)
|
||||||
++OrderPos;
|
++OrderPos;
|
||||||
else
|
else
|
||||||
@@ -6701,9 +6717,9 @@ TController::UpdateConnect() {
|
|||||||
// podłączanie do składu
|
// podłączanie do składu
|
||||||
if (iDrivigFlags & moveConnect) {
|
if (iDrivigFlags & moveConnect) {
|
||||||
// sprzęgi sprawdzamy w pierwszej kolejności, bo jak połączony, to koniec
|
// sprzęgi sprawdzamy w pierwszej kolejności, bo jak połączony, to koniec
|
||||||
auto *vehicle { pVehicles[ end::front ] };
|
auto *vehicle { iCouplingVehicle.value().first };
|
||||||
|
auto const couplingend { iCouplingVehicle.value().second };
|
||||||
auto *vehicleparameters { vehicle->MoverParameters };
|
auto *vehicleparameters { vehicle->MoverParameters };
|
||||||
auto const couplingend { ( vehicle->DirectionGet() > 0 ? end::front : end::rear ) };
|
|
||||||
if( vehicleparameters->Couplers[ couplingend ].CouplingFlag != iCoupler ) {
|
if( vehicleparameters->Couplers[ couplingend ].CouplingFlag != iCoupler ) {
|
||||||
auto const &neighbour { vehicleparameters->Neighbours[ couplingend ] };
|
auto const &neighbour { vehicleparameters->Neighbours[ couplingend ] };
|
||||||
if( neighbour.vehicle != nullptr ) {
|
if( neighbour.vehicle != nullptr ) {
|
||||||
@@ -6736,14 +6752,24 @@ TController::UpdateConnect() {
|
|||||||
CheckVehicles( Connect ); // sprawdzić światła nowego składu
|
CheckVehicles( Connect ); // sprawdzić światła nowego składu
|
||||||
|
|
||||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||||
|
iCouplingVehicle.reset();
|
||||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||||
JumpToNextOrder(); // wykonanie następnej komendy
|
JumpToNextOrder( true ); // wykonanie następnej komendy
|
||||||
}
|
}
|
||||||
} // moveConnect
|
} // moveConnect
|
||||||
else {
|
else {
|
||||||
|
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
||||||
if( Obstacle.distance <= 20.0 ) {
|
if( Obstacle.distance <= 20.0 ) {
|
||||||
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
if( !iCouplingVehicle ) {
|
||||||
iDrivigFlags |= moveConnect;
|
// write down which vehicle should be coupled with the target consist,
|
||||||
|
// so we don't lose track of it if the user does something unexpected
|
||||||
|
iCouplingVehicle = {
|
||||||
|
pVehicles[ end::front ],
|
||||||
|
( pVehicles[ end::front ]->DirectionGet() > 0 ?
|
||||||
|
end::front :
|
||||||
|
end::rear ) };
|
||||||
|
iDrivigFlags |= moveConnect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6885,9 +6911,7 @@ TController::UpdateDisconnect() {
|
|||||||
// 5th stage: clean up and move on to next order
|
// 5th stage: clean up and move on to next order
|
||||||
if( iDirection == iDirectionOrder ) {
|
if( iDirection == iDirectionOrder ) {
|
||||||
iDrivigFlags &= ~movePress; // koniec dociskania
|
iDrivigFlags &= ~movePress; // koniec dociskania
|
||||||
while( ( OrderCurrentGet() & Disconnect ) != 0 ) {
|
JumpToNextOrder( true ); // zmieni światła
|
||||||
JumpToNextOrder(); // zmieni światła
|
|
||||||
}
|
|
||||||
TableClear(); // skanowanie od nowa
|
TableClear(); // skanowanie od nowa
|
||||||
iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem
|
iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem
|
||||||
}
|
}
|
||||||
@@ -6957,6 +6981,11 @@ TController::handle_orders() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
// special case, change_direction potentially received during partially completed coupling operation
|
||||||
|
// this is unlikely to happen for the AI, but can happen for a (slower) human user
|
||||||
|
if( TestFlag( iDrivigFlags, moveConnect ) ) {
|
||||||
|
UpdateConnect();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // switch OrderList[OrderPos]
|
} // switch OrderList[OrderPos]
|
||||||
@@ -7949,27 +7978,31 @@ TController::check_route_ahead( double const Range ) {
|
|||||||
void
|
void
|
||||||
TController::check_route_behind( double const Range ) {
|
TController::check_route_behind( double const Range ) {
|
||||||
|
|
||||||
if( VelNext != 0.0 ) { return; }
|
if( VelNext != 0.0 ) { return; } // not if we can move ahead
|
||||||
|
if( TestFlag( iDrivigFlags, moveConnect ) ) { return; } // not if we're in middle of coupling operation
|
||||||
|
|
||||||
if( !( OrderCurrentGet() & ~( Shunt | Loose_shunt | Connect ) ) ) {
|
if( ( OrderCurrentGet() & ~( Shunt | Loose_shunt | Connect ) ) == 0 ) {
|
||||||
// jedzie w Shunt albo Connect, albo Wait_for_orders
|
// jedzie w Shunt albo Connect, albo Wait_for_orders
|
||||||
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie ma taboru do podłączenia
|
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie ma taboru do podłączenia
|
||||||
if( ( ( OrderCurrentGet() & Connect ) == 0 )
|
auto const couplinginprogress {
|
||||||
|| ( Obstacle.distance > std::min( 2000.0, FirstSemaphorDist ) ) ) {
|
( TestFlag( OrderCurrentGet(), Connect ) )
|
||||||
auto const comm { BackwardScan( Range ) };
|
&& ( ( Obstacle.distance < std::min( 2000.0, FirstSemaphorDist ) )
|
||||||
if( comm != TCommandType::cm_Unknown ) {
|
|| ( TestFlag( iDrivigFlags, moveConnect ) ) ) };
|
||||||
// jeśli w drugą można jechać
|
if( couplinginprogress ) { return; }
|
||||||
// należy sprawdzać odległość od znalezionego sygnalizatora,
|
|
||||||
// aby w przypadku prędkości 0.1 wyciągnąć najpierw skład za sygnalizator
|
auto const comm { BackwardScan( Range ) };
|
||||||
// i dopiero wtedy zmienić kierunek jazdy, oczekując podania prędkości >0.5
|
if( comm != TCommandType::cm_Unknown ) {
|
||||||
if( comm == TCommandType::cm_Command ) {
|
// jeśli w drugą można jechać
|
||||||
// jeśli komenda Shunt to ją odbierz bez przemieszczania się (np. odczep wagony po dopchnięciu do końca toru)
|
// należy sprawdzać odległość od znalezionego sygnalizatora,
|
||||||
iDrivigFlags |= moveStopHere;
|
// aby w przypadku prędkości 0.1 wyciągnąć najpierw skład za sygnalizator
|
||||||
}
|
// i dopiero wtedy zmienić kierunek jazdy, oczekując podania prędkości >0.5
|
||||||
iDirectionOrder = -iDirection; // zmiana kierunku jazdy
|
if( comm == TCommandType::cm_Command ) {
|
||||||
// zmiana kierunku bez psucia kolejnych komend
|
// jeśli komenda Shunt to ją odbierz bez przemieszczania się (np. odczep wagony po dopchnięciu do końca toru)
|
||||||
OrderList[ OrderPos ] = TOrders( OrderCurrentGet() | Change_direction );
|
iDrivigFlags |= moveStopHere;
|
||||||
}
|
}
|
||||||
|
iDirectionOrder = -iDirection; // zmiana kierunku jazdy
|
||||||
|
// zmiana kierunku bez psucia kolejnych komend
|
||||||
|
OrderList[ OrderPos ] = TOrders( OrderCurrentGet() | Change_direction );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
Driver.h
3
Driver.h
@@ -383,6 +383,7 @@ private:
|
|||||||
int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
|
int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
|
||||||
int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku)
|
int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku)
|
||||||
std::optional<int> iDirectionBackup; // consist direction to be restored after coupling/uncoupling and similar direction-changing operations
|
std::optional<int> iDirectionBackup; // consist direction to be restored after coupling/uncoupling and similar direction-changing operations
|
||||||
|
std::optional<std::pair<TDynamicObject*,int>> iCouplingVehicle; // <vehicle, coupler> to be coupled with another consist in current coupling operation
|
||||||
int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)
|
int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)
|
||||||
int iCoupler = 0; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
int iCoupler = 0; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
||||||
int iDriverFailCount = 0; // licznik błędów AI
|
int iDriverFailCount = 0; // licznik błędów AI
|
||||||
@@ -446,7 +447,7 @@ public:
|
|||||||
std::string OrderCurrent() const;
|
std::string OrderCurrent() const;
|
||||||
private:
|
private:
|
||||||
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
||||||
void JumpToNextOrder();
|
void JumpToNextOrder( bool const Skipmergedchangedirection = false );
|
||||||
void JumpToFirstOrder();
|
void JumpToFirstOrder();
|
||||||
void OrderPush( TOrders NewOrder );
|
void OrderPush( TOrders NewOrder );
|
||||||
void OrderNext( TOrders NewOrder );
|
void OrderNext( TOrders NewOrder );
|
||||||
|
|||||||
16
DynObj.cpp
16
DynObj.cpp
@@ -4122,6 +4122,14 @@ void TDynamicObject::RenderSounds() {
|
|||||||
sHeater.stop();
|
sHeater.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// battery sound
|
||||||
|
if( MoverParameters->Battery ) {
|
||||||
|
m_batterysound.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_batterysound.stop();
|
||||||
|
}
|
||||||
|
|
||||||
// brake system and braking sounds:
|
// brake system and braking sounds:
|
||||||
|
|
||||||
// brake cylinder piston
|
// brake cylinder piston
|
||||||
@@ -5763,6 +5771,12 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
sHeater.owner( this );
|
sHeater.owner( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( token == "battery:" ) {
|
||||||
|
// train heating device
|
||||||
|
m_batterysound.deserialize( parser, sound_type::single );
|
||||||
|
m_batterysound.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
else if( token == "turbo:" ) {
|
else if( token == "turbo:" ) {
|
||||||
// pliki z turbogeneratorem
|
// pliki z turbogeneratorem
|
||||||
m_powertrainsounds.engine_turbo.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
m_powertrainsounds.engine_turbo.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
@@ -6484,7 +6498,7 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
// other engine compartment sounds
|
// other engine compartment sounds
|
||||||
auto const nullvector { glm::vec3() };
|
auto const nullvector { glm::vec3() };
|
||||||
std::vector<sound_source *> enginesounds = {
|
std::vector<sound_source *> enginesounds = {
|
||||||
&sConverter, &sCompressor, &sCompressorIdle, &sSmallCompressor, &sHeater
|
&sConverter, &sCompressor, &sCompressorIdle, &sSmallCompressor, &sHeater, &m_batterysound
|
||||||
};
|
};
|
||||||
for( auto sound : enginesounds ) {
|
for( auto sound : enginesounds ) {
|
||||||
if( sound->offset() == nullvector ) {
|
if( sound->offset() == nullvector ) {
|
||||||
|
|||||||
1
DynObj.h
1
DynObj.h
@@ -480,6 +480,7 @@ private:
|
|||||||
sound_source sCompressorIdle { sound_placement::engine };
|
sound_source sCompressorIdle { sound_placement::engine };
|
||||||
sound_source sSmallCompressor { sound_placement::engine };
|
sound_source sSmallCompressor { sound_placement::engine };
|
||||||
sound_source sHeater { sound_placement::engine };
|
sound_source sHeater { sound_placement::engine };
|
||||||
|
sound_source m_batterysound { sound_placement::engine };
|
||||||
// braking sounds
|
// braking sounds
|
||||||
sound_source dsbPneumaticRelay { sound_placement::external };
|
sound_source dsbPneumaticRelay { sound_placement::external };
|
||||||
sound_source rsBrake { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
sound_source rsBrake { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||||
|
|||||||
13
Event.cpp
13
Event.cpp
@@ -538,10 +538,10 @@ updatevalues_event::run_() {
|
|||||||
auto const location { targetcell->location() };
|
auto const location { targetcell->location() };
|
||||||
for( auto vehicle : targetcell->Track->Dynamics ) {
|
for( auto vehicle : targetcell->Track->Dynamics ) {
|
||||||
if( vehicle->Mechanik ) {
|
if( vehicle->Mechanik ) {
|
||||||
|
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
|
||||||
targetcell->PutCommand(
|
targetcell->PutCommand(
|
||||||
vehicle->Mechanik,
|
vehicle->Mechanik,
|
||||||
&location );
|
&location );
|
||||||
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -775,10 +775,9 @@ putvalues_event::run_() {
|
|||||||
m_input.location.z,
|
m_input.location.z,
|
||||||
m_input.location.y };
|
m_input.location.y };
|
||||||
|
|
||||||
std::string vehiclename;
|
|
||||||
if( m_activator->Mechanik ) {
|
if( m_activator->Mechanik ) {
|
||||||
// przekazanie rozkazu do AI
|
// przekazanie rozkazu do AI
|
||||||
vehiclename = m_activator->Mechanik->Vehicle()->name();
|
WriteLog( " Vehicle: [" + m_activator->Mechanik->Vehicle()->name() + "]" );
|
||||||
m_activator->Mechanik->PutCommand(
|
m_activator->Mechanik->PutCommand(
|
||||||
m_input.data_text,
|
m_input.data_text,
|
||||||
m_input.data_value_1,
|
m_input.data_value_1,
|
||||||
@@ -790,7 +789,7 @@ putvalues_event::run_() {
|
|||||||
// send the command to consist owner,
|
// send the command to consist owner,
|
||||||
// we're acting on presumption there's hardly ever need to issue command to unmanned vehicle
|
// we're acting on presumption there's hardly ever need to issue command to unmanned vehicle
|
||||||
// and the intended recipient moved between vehicles after the event was queued
|
// and the intended recipient moved between vehicles after the event was queued
|
||||||
vehiclename = m_activator->ctOwner->Vehicle()->name();
|
WriteLog( " Vehicle: [" + m_activator->ctOwner->Vehicle()->name() + "]" );
|
||||||
m_activator->ctOwner->PutCommand(
|
m_activator->ctOwner->PutCommand(
|
||||||
m_input.data_text,
|
m_input.data_text,
|
||||||
m_input.data_value_1,
|
m_input.data_value_1,
|
||||||
@@ -799,15 +798,13 @@ putvalues_event::run_() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// przekazanie do pojazdu
|
// przekazanie do pojazdu
|
||||||
vehiclename = m_activator->name();
|
WriteLog( " Vehicle: [" + m_activator->name() +"]" );
|
||||||
m_activator->MoverParameters->PutCommand(
|
m_activator->MoverParameters->PutCommand(
|
||||||
m_input.data_text,
|
m_input.data_text,
|
||||||
m_input.data_value_1,
|
m_input.data_value_1,
|
||||||
m_input.data_value_2,
|
m_input.data_value_2,
|
||||||
loc );
|
loc );
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteLog( " Vehicle: [" + vehiclename + "]" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// export_as_text() subclass details
|
// export_as_text() subclass details
|
||||||
@@ -944,10 +941,10 @@ copyvalues_event::run_() {
|
|||||||
auto const location { targetcell->location() };
|
auto const location { targetcell->location() };
|
||||||
for( auto vehicle : targetcell->Track->Dynamics ) {
|
for( auto vehicle : targetcell->Track->Dynamics ) {
|
||||||
if( vehicle->Mechanik ) {
|
if( vehicle->Mechanik ) {
|
||||||
|
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
|
||||||
targetcell->PutCommand(
|
targetcell->PutCommand(
|
||||||
vehicle->Mechanik,
|
vehicle->Mechanik,
|
||||||
&location );
|
&location );
|
||||||
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
Gauge.cpp
59
Gauge.cpp
@@ -141,8 +141,32 @@ void TGauge::Load( cParser &Parser, TDynamicObject const *Owner, double const mu
|
|||||||
>> endscale;
|
>> endscale;
|
||||||
}
|
}
|
||||||
// new, variable length section
|
// new, variable length section
|
||||||
while( true == Load_mapping( Parser ) ) {
|
{
|
||||||
; // all work done by while()
|
scratch_data scratchpad;
|
||||||
|
while( true == Load_mapping( Parser, scratchpad ) ) {
|
||||||
|
; // all work done by while()
|
||||||
|
}
|
||||||
|
// post-deserialization cleanup
|
||||||
|
// set provided custom soundproofing to assigned sounds (for sounds without their own custom soundproofing)
|
||||||
|
if( scratchpad.soundproofing ) {
|
||||||
|
if( !m_soundfxincrease.soundproofing() ) {
|
||||||
|
m_soundfxincrease.soundproofing() = scratchpad.soundproofing;
|
||||||
|
}
|
||||||
|
if( !m_soundfxdecrease.soundproofing() ) {
|
||||||
|
m_soundfxdecrease.soundproofing() = scratchpad.soundproofing;
|
||||||
|
}
|
||||||
|
if( !m_soundfxon.soundproofing() ) {
|
||||||
|
m_soundfxon.soundproofing() = scratchpad.soundproofing;
|
||||||
|
}
|
||||||
|
if( !m_soundfxoff.soundproofing() ) {
|
||||||
|
m_soundfxoff.soundproofing() = scratchpad.soundproofing;
|
||||||
|
}
|
||||||
|
for( auto &soundfxrecord : m_soundfxvalues ) {
|
||||||
|
if( !soundfxrecord.second.soundproofing() ) {
|
||||||
|
soundfxrecord.second.soundproofing() = scratchpad.soundproofing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +231,7 @@ void TGauge::Load( cParser &Parser, TDynamicObject const *Owner, double const mu
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TGauge::Load_mapping( cParser &Input ) {
|
TGauge::Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// token can be a key or block end
|
// token can be a key or block end
|
||||||
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
||||||
@@ -236,8 +260,21 @@ TGauge::Load_mapping( cParser &Input ) {
|
|||||||
else if( key == "soundoff:" ) {
|
else if( key == "soundoff:" ) {
|
||||||
m_soundfxoff.deserialize( Input, sound_type::single );
|
m_soundfxoff.deserialize( Input, sound_type::single );
|
||||||
}
|
}
|
||||||
else if( key.compare( 0, std::min<std::size_t>( key.size(), 5 ), "sound" ) == 0 ) {
|
else if( key == "soundproofing:" ) {
|
||||||
// sounds assigned to specific gauge values, defined by key soundFoo: where Foo = value
|
// custom soundproofing in format [ p1, p2, p3, p4, p5, p6 ]
|
||||||
|
Input.getTokens( 6, false, "\n\r\t ,;[]" );
|
||||||
|
std::array<float, 6> soundproofing;
|
||||||
|
Input
|
||||||
|
>> soundproofing[ 0 ]
|
||||||
|
>> soundproofing[ 1 ]
|
||||||
|
>> soundproofing[ 2 ]
|
||||||
|
>> soundproofing[ 3 ]
|
||||||
|
>> soundproofing[ 4 ]
|
||||||
|
>> soundproofing[ 5 ];
|
||||||
|
Scratchpad.soundproofing = soundproofing;
|
||||||
|
}
|
||||||
|
else if( starts_with( key, "sound" ) ) {
|
||||||
|
// sounds assigned to specific gauge values, defined by key soundX: where X = value
|
||||||
auto const indexstart { key.find_first_of( "-1234567890" ) };
|
auto const indexstart { key.find_first_of( "-1234567890" ) };
|
||||||
auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
|
auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
|
||||||
if( indexstart != std::string::npos ) {
|
if( indexstart != std::string::npos ) {
|
||||||
@@ -290,13 +327,19 @@ TGauge::UpdateValue( float fNewDesired, sound_source *Fallbacksound ) {
|
|||||||
// HACK: crude way to discern controls with continuous and quantized value range
|
// HACK: crude way to discern controls with continuous and quantized value range
|
||||||
if( currentvalue < fNewDesired ) {
|
if( currentvalue < fNewDesired ) {
|
||||||
// shift up
|
// shift up
|
||||||
m_soundfxincrease.play( m_soundtype );
|
if( false == m_soundfxincrease.empty() ) {
|
||||||
|
m_soundfxincrease.play( m_soundtype );
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( currentvalue > fNewDesired ) {
|
else if( currentvalue > fNewDesired ) {
|
||||||
// shift down
|
// shift down
|
||||||
m_soundfxdecrease.play( m_soundtype );
|
if( false == m_soundfxdecrease.empty() ) {
|
||||||
|
m_soundfxdecrease.play( m_soundtype );
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( Fallbacksound != nullptr ) {
|
if( Fallbacksound != nullptr ) {
|
||||||
// ...and if that fails too, try the provided fallback sound from legacy system
|
// ...and if that fails too, try the provided fallback sound from legacy system
|
||||||
Fallbacksound->play( m_soundtype );
|
Fallbacksound->play( m_soundtype );
|
||||||
}
|
}
|
||||||
|
|||||||
8
Gauge.h
8
Gauge.h
@@ -71,10 +71,14 @@ public:
|
|||||||
*SubModelOn { nullptr }; // optional submodel visible when the state input is set
|
*SubModelOn { nullptr }; // optional submodel visible when the state input is set
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// types
|
||||||
|
struct scratch_data {
|
||||||
|
std::optional< std::array<float, 6> > soundproofing;
|
||||||
|
};
|
||||||
// methods
|
// methods
|
||||||
// imports member data pair from the config file
|
// imports member data pair from the config file
|
||||||
bool
|
bool
|
||||||
Load_mapping( cParser &Input );
|
Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad );
|
||||||
void
|
void
|
||||||
UpdateValue( float fNewDesired, sound_source *Fallbacksound );
|
UpdateValue( float fNewDesired, sound_source *Fallbacksound );
|
||||||
float
|
float
|
||||||
|
|||||||
@@ -1046,7 +1046,7 @@ public:
|
|||||||
double EngineHeatingRPM { 0.0 }; // guaranteed engine revolutions with heating enabled
|
double EngineHeatingRPM { 0.0 }; // guaranteed engine revolutions with heating enabled
|
||||||
double LightPower = 0.0; /*moc pobierana na ogrzewanie/oswietlenie*/
|
double LightPower = 0.0; /*moc pobierana na ogrzewanie/oswietlenie*/
|
||||||
double BatteryVoltage = 0.0; /*Winger - baterie w elektrykach*/
|
double BatteryVoltage = 0.0; /*Winger - baterie w elektrykach*/
|
||||||
bool Battery = false; /*Czy sa zalavzone baterie*/
|
bool Battery = false; /*Czy sa zalaczone baterie*/
|
||||||
start_t BatteryStart = start_t::manual;
|
start_t BatteryStart = start_t::manual;
|
||||||
bool EpFuse = true; /*Czy sa zalavzone baterie*/
|
bool EpFuse = true; /*Czy sa zalavzone baterie*/
|
||||||
bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/
|
bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/
|
||||||
@@ -1805,8 +1805,10 @@ public:
|
|||||||
bool ConverterSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl przetwornicy*/
|
bool ConverterSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl przetwornicy*/
|
||||||
bool CompressorSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl sprezarki*/
|
bool CompressorSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl sprezarki*/
|
||||||
bool ChangeCompressorPreset( int const Change, range_t const Notify = range_t::consist );
|
bool ChangeCompressorPreset( int const Change, range_t const Notify = range_t::consist );
|
||||||
|
bool HeatingSwitch( bool const State, range_t const Notify = range_t::consist );
|
||||||
|
void HeatingSwitch_( bool const State );
|
||||||
|
|
||||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||||
void LowVoltagePowerCheck( double const Deltatime );
|
void LowVoltagePowerCheck( double const Deltatime );
|
||||||
void MainsCheck( double const Deltatime );
|
void MainsCheck( double const Deltatime );
|
||||||
void PowerCouplersCheck( double const Deltatime, coupling const Coupling );
|
void PowerCouplersCheck( double const Deltatime, coupling const Coupling );
|
||||||
|
|||||||
@@ -647,10 +647,12 @@ bool TMoverParameters::ChangeCab(int direction)
|
|||||||
// rozruch wysoki (true) albo niski (false)
|
// rozruch wysoki (true) albo niski (false)
|
||||||
bool
|
bool
|
||||||
TMoverParameters::CurrentSwitch(bool const State) {
|
TMoverParameters::CurrentSwitch(bool const State) {
|
||||||
// Ra: przeniosłem z Train.cpp, nie wiem czy ma to sens
|
|
||||||
if (MaxCurrentSwitch(State)) {
|
if( MaxCurrentSwitch( State ) ) {
|
||||||
if (TrainType != dt_EZT)
|
if( TrainType != dt_EZT ) {
|
||||||
return (MinCurrentSwitch(State));
|
( MinCurrentSwitch( State ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// TBD, TODO: split off shunt mode toggle into a separate command? It doesn't make much sense to have these two together like that
|
// TBD, TODO: split off shunt mode toggle into a separate command? It doesn't make much sense to have these two together like that
|
||||||
// dla 2Ls150
|
// dla 2Ls150
|
||||||
@@ -3641,6 +3643,33 @@ bool TMoverParameters::ChangeCompressorPreset( int const State, range_t const No
|
|||||||
return ( CompressorListPos != initialstate );
|
return ( CompressorListPos != initialstate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TMoverParameters::HeatingSwitch( bool const State, range_t const Notify ) {
|
||||||
|
|
||||||
|
bool const initialstate { HeatingAllow };
|
||||||
|
|
||||||
|
HeatingSwitch_( State );
|
||||||
|
|
||||||
|
if( Notify != range_t::local ) {
|
||||||
|
// pass the command to other vehicles
|
||||||
|
// TBD: pass the requested state, or the actual state?
|
||||||
|
SendCtrlToNext(
|
||||||
|
"HeatingSwitch",
|
||||||
|
( State ? 1 : 0 ),
|
||||||
|
CabActive,
|
||||||
|
( Notify == range_t::unit ?
|
||||||
|
coupling::control | coupling::permanent :
|
||||||
|
coupling::control ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( HeatingAllow != initialstate );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TMoverParameters::HeatingSwitch_( bool const State ) {
|
||||||
|
|
||||||
|
// TBD, TODO: activation dependencies?
|
||||||
|
HeatingAllow = State;
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160711
|
// Q: 20160711
|
||||||
// zwiększenie nastawy hamulca
|
// zwiększenie nastawy hamulca
|
||||||
@@ -6550,12 +6579,14 @@ bool TMoverParameters::MaxCurrentSwitch(bool State)
|
|||||||
if (State && (Imax == ImaxLo) && (RList[MainCtrlPos].Bn < 2) &&
|
if (State && (Imax == ImaxLo) && (RList[MainCtrlPos].Bn < 2) &&
|
||||||
!((TrainType == dt_ET42) && (MainCtrlPos > 0)))
|
!((TrainType == dt_ET42) && (MainCtrlPos > 0)))
|
||||||
{
|
{
|
||||||
|
|
||||||
Imax = ImaxHi;
|
Imax = ImaxHi;
|
||||||
MCS = true;
|
MCS = true;
|
||||||
if (CabActive != 0)
|
if (CabActive != 0)
|
||||||
SendCtrlToNext("MaxCurrentSwitch", 1, CabActive);
|
SendCtrlToNext("MaxCurrentSwitch", 1, CabActive);
|
||||||
}
|
}
|
||||||
if (!State)
|
if (!State)
|
||||||
|
|
||||||
if (Imax == ImaxHi)
|
if (Imax == ImaxHi)
|
||||||
if (!((TrainType == dt_ET42) && (MainCtrlPos > 0)))
|
if (!((TrainType == dt_ET42) && (MainCtrlPos > 0)))
|
||||||
{
|
{
|
||||||
@@ -11771,6 +11802,11 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
MainSwitch_( CValue1 > 0.0 );
|
MainSwitch_( CValue1 > 0.0 );
|
||||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
}
|
}
|
||||||
|
else if (Command == "HeatingSwitch")
|
||||||
|
{
|
||||||
|
HeatingSwitch_( CValue1 > 0.0 );
|
||||||
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
|
}
|
||||||
else if (Command == "Direction")
|
else if (Command == "Direction")
|
||||||
{
|
{
|
||||||
DirActive = static_cast<int>(floor(CValue1));
|
DirActive = static_cast<int>(floor(CValue1));
|
||||||
|
|||||||
48
Train.cpp
48
Train.cpp
@@ -4859,7 +4859,7 @@ void TTrain::OnCommand_heatingenable( TTrain *Train, command_data const &Command
|
|||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
|
||||||
Train->mvControlled->HeatingAllow = true;
|
Train->mvOccupied->HeatingSwitch( true );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggTrainHeatingButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggTrainHeatingButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
@@ -4869,7 +4869,7 @@ void TTrain::OnCommand_heatingdisable( TTrain *Train, command_data const &Comman
|
|||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
|
||||||
Train->mvControlled->HeatingAllow = false;
|
Train->mvOccupied->HeatingSwitch( false );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggTrainHeatingButton.UpdateValue(
|
Train->ggTrainHeatingButton.UpdateValue(
|
||||||
( Train->ggTrainHeatingButton.type() == TGaugeType::push ?
|
( Train->ggTrainHeatingButton.type() == TGaugeType::push ?
|
||||||
@@ -7101,7 +7101,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
ggMainCtrl.Update();
|
ggMainCtrl.Update();
|
||||||
}
|
}
|
||||||
if (ggMainCtrlAct.SubModel)
|
if (ggMainCtrlAct.SubModel != nullptr )
|
||||||
{
|
{
|
||||||
if (mvControlled->CoupledCtrl)
|
if (mvControlled->CoupledCtrl)
|
||||||
ggMainCtrlAct.UpdateValue(
|
ggMainCtrlAct.UpdateValue(
|
||||||
@@ -7110,7 +7110,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggMainCtrlAct.UpdateValue(double(mvControlled->MainCtrlActualPos));
|
ggMainCtrlAct.UpdateValue(double(mvControlled->MainCtrlActualPos));
|
||||||
ggMainCtrlAct.Update();
|
ggMainCtrlAct.Update();
|
||||||
}
|
}
|
||||||
if (ggScndCtrl.SubModel) {
|
if (ggScndCtrl.SubModel != nullptr ) {
|
||||||
// Ra: od byte odejmowane boolean i konwertowane potem na double?
|
// Ra: od byte odejmowane boolean i konwertowane potem na double?
|
||||||
ggScndCtrl.UpdateValue(
|
ggScndCtrl.UpdateValue(
|
||||||
double( mvControlled->ScndCtrlPos
|
double( mvControlled->ScndCtrlPos
|
||||||
@@ -7118,26 +7118,34 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
dsbNastawnikBocz );
|
dsbNastawnikBocz );
|
||||||
ggScndCtrl.Update();
|
ggScndCtrl.Update();
|
||||||
}
|
}
|
||||||
if( ggScndCtrlButton.is_toggle() ) {
|
if( ggScndCtrlButton.SubModel != nullptr ) {
|
||||||
ggScndCtrlButton.UpdateValue(
|
if( ggScndCtrlButton.is_toggle() ) {
|
||||||
( ( mvControlled->ScndCtrlPos > 0 ) ? 1.f : 0.f ),
|
ggScndCtrlButton.UpdateValue(
|
||||||
dsbSwitch );
|
( ( mvControlled->ScndCtrlPos > 0 ) ? 1.f : 0.f ),
|
||||||
|
dsbSwitch );
|
||||||
|
}
|
||||||
|
ggScndCtrlButton.Update( lowvoltagepower );
|
||||||
}
|
}
|
||||||
ggScndCtrlButton.Update( lowvoltagepower );
|
if( ggScndCtrlOffButton.SubModel != nullptr ) {
|
||||||
ggScndCtrlOffButton.Update( lowvoltagepower );
|
ggScndCtrlOffButton.Update( lowvoltagepower );
|
||||||
ggDistanceCounterButton.Update();
|
}
|
||||||
if (ggDirKey.SubModel) {
|
if( ggDistanceCounterButton.SubModel != nullptr ) {
|
||||||
if (mvControlled->TrainType != dt_EZT)
|
ggDistanceCounterButton.Update();
|
||||||
|
}
|
||||||
|
if (ggDirKey.SubModel != nullptr ) {
|
||||||
|
if( mvControlled->TrainType != dt_EZT ) {
|
||||||
ggDirKey.UpdateValue(
|
ggDirKey.UpdateValue(
|
||||||
double(mvControlled->DirActive),
|
double( mvControlled->DirActive ),
|
||||||
dsbReverserKey);
|
dsbReverserKey );
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
ggDirKey.UpdateValue(
|
ggDirKey.UpdateValue(
|
||||||
double(mvControlled->DirActive) + double(mvControlled->Imin == mvControlled->IminHi),
|
double( mvControlled->DirActive ) + double( mvControlled->Imin == mvControlled->IminHi ),
|
||||||
dsbReverserKey);
|
dsbReverserKey );
|
||||||
|
}
|
||||||
ggDirKey.Update();
|
ggDirKey.Update();
|
||||||
}
|
}
|
||||||
if (ggBrakeCtrl.SubModel)
|
if (ggBrakeCtrl.SubModel != nullptr )
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (DynamicObject->Mechanik ?
|
if (DynamicObject->Mechanik ?
|
||||||
@@ -9437,7 +9445,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "universal7:", ggUniversals[ 7 ] },
|
{ "universal7:", ggUniversals[ 7 ] },
|
||||||
{ "universal8:", ggUniversals[ 8 ] },
|
{ "universal8:", ggUniversals[ 8 ] },
|
||||||
{ "universal9:", ggUniversals[ 9 ] }
|
{ "universal9:", ggUniversals[ 9 ] }
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
auto const lookup { gauges.find( Label ) };
|
auto const lookup { gauges.find( Label ) };
|
||||||
if( lookup != gauges.end() ) {
|
if( lookup != gauges.end() ) {
|
||||||
|
|||||||
@@ -1147,24 +1147,24 @@ TController::cue_action( locale::string const Action, float const Actionparamete
|
|||||||
// consist heating
|
// consist heating
|
||||||
case locale::string::driver_hint_consistheatingon: {
|
case locale::string::driver_hint_consistheatingon: {
|
||||||
if( AIControllFlag ) {
|
if( AIControllFlag ) {
|
||||||
mvControlling->HeatingAllow = true;
|
mvOccupied->HeatingSwitch( true );
|
||||||
}
|
}
|
||||||
remove_hint( locale::string::driver_hint_consistheatingoff );
|
remove_hint( locale::string::driver_hint_consistheatingoff );
|
||||||
hint(
|
hint(
|
||||||
Action,
|
Action,
|
||||||
[this](float const Parameter) -> bool {
|
[this](float const Parameter) -> bool {
|
||||||
return ( mvControlling->HeatingAllow == true ); } );
|
return ( mvOccupied->HeatingAllow == true ); } );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case locale::string::driver_hint_consistheatingoff: {
|
case locale::string::driver_hint_consistheatingoff: {
|
||||||
if( AIControllFlag ) {
|
if( AIControllFlag ) {
|
||||||
mvControlling->HeatingAllow = false;
|
mvOccupied->HeatingSwitch( false );
|
||||||
}
|
}
|
||||||
remove_hint( locale::string::driver_hint_consistheatingon );
|
remove_hint( locale::string::driver_hint_consistheatingon );
|
||||||
hint(
|
hint(
|
||||||
Action,
|
Action,
|
||||||
[this](float const Parameter) -> bool {
|
[this](float const Parameter) -> bool {
|
||||||
return ( mvControlling->HeatingAllow == false ); } );
|
return ( mvOccupied->HeatingAllow == false ); } );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1088,7 +1088,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
|||||||
// biezaca komenda dla AI
|
// biezaca komenda dla AI
|
||||||
auto textline =
|
auto textline =
|
||||||
"Current order: [" + std::to_string( mechanik.OrderPos ) + "] "
|
"Current order: [" + std::to_string( mechanik.OrderPos ) + "] "
|
||||||
+ mechanik.OrderCurrent();
|
+ mechanik.Order2Str( mechanik.OrderCurrentGet() );
|
||||||
|
|
||||||
if( mechanik.fStopTime < 0.0 ) {
|
if( mechanik.fStopTime < 0.0 ) {
|
||||||
textline += "\n stop time: " + to_string( std::abs( mechanik.fStopTime ), 1 );
|
textline += "\n stop time: " + to_string( std::abs( mechanik.fStopTime ), 1 );
|
||||||
|
|||||||
39
sound.cpp
39
sound.cpp
@@ -171,10 +171,23 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
|||||||
else if( key == "soundend:" ) {
|
else if( key == "soundend:" ) {
|
||||||
sound( sound_id::end ).buffer = audio::renderer.fetch_buffer( deserialize_random_set( Input, "\n\r\t ,;" ) );
|
sound( sound_id::end ).buffer = audio::renderer.fetch_buffer( deserialize_random_set( Input, "\n\r\t ,;" ) );
|
||||||
}
|
}
|
||||||
else if( key.compare( 0, std::min<std::size_t>( key.size(), 5 ), "sound" ) == 0 ) {
|
else if( key == "soundproofing:" ) {
|
||||||
|
// custom soundproofing in format [ p1, p2, p3, p4, p5, p6 ]
|
||||||
|
Input.getTokens( 6, false, "\n\r\t ,;[]" );
|
||||||
|
std::array<float, 6> soundproofing;
|
||||||
|
Input
|
||||||
|
>> soundproofing[ 0 ]
|
||||||
|
>> soundproofing[ 1 ]
|
||||||
|
>> soundproofing[ 2 ]
|
||||||
|
>> soundproofing[ 3 ]
|
||||||
|
>> soundproofing[ 4 ]
|
||||||
|
>> soundproofing[ 5 ];
|
||||||
|
m_soundproofing = soundproofing;
|
||||||
|
}
|
||||||
|
else if( starts_with( key, "sound" ) ) {
|
||||||
// sound chunks, defined with key soundX where X = activation threshold
|
// sound chunks, defined with key soundX where X = activation threshold
|
||||||
auto const indexstart { key.find_first_of( "1234567890" ) };
|
auto const indexstart { key.find_first_of( "-1234567890" ) };
|
||||||
auto const indexend { key.find_first_not_of( "1234567890", indexstart ) };
|
auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
|
||||||
if( indexstart != std::string::npos ) {
|
if( indexstart != std::string::npos ) {
|
||||||
// NOTE: we'll sort the chunks at the end of deserialization
|
// NOTE: we'll sort the chunks at the end of deserialization
|
||||||
m_soundchunks.emplace_back(
|
m_soundchunks.emplace_back(
|
||||||
@@ -202,10 +215,10 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
|||||||
Input.getToken<float>( false, "\n\r\t ,;" ),
|
Input.getToken<float>( false, "\n\r\t ,;" ),
|
||||||
0.0f, 1.0f );
|
0.0f, 1.0f );
|
||||||
}
|
}
|
||||||
else if( key.compare( 0, std::min<std::size_t>( key.size(), 5 ), "pitch" ) == 0 ) {
|
else if( starts_with( key, "pitch" ) ) {
|
||||||
// sound chunk pitch, defined with key pitchX where X = activation threshold
|
// sound chunk pitch, defined with key pitchX where X = activation threshold
|
||||||
auto const indexstart { key.find_first_of( "1234567890" ) };
|
auto const indexstart { key.find_first_of( "-1234567890" ) };
|
||||||
auto const indexend { key.find_first_not_of( "1234567890", indexstart ) };
|
auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
|
||||||
if( indexstart != std::string::npos ) {
|
if( indexstart != std::string::npos ) {
|
||||||
auto const index { std::stoi( key.substr( indexstart, indexend - indexstart ) ) };
|
auto const index { std::stoi( key.substr( indexstart, indexend - indexstart ) ) };
|
||||||
auto const pitch { Input.getToken<float>( false, "\n\r\t ,;" ) };
|
auto const pitch { Input.getToken<float>( false, "\n\r\t ,;" ) };
|
||||||
@@ -962,12 +975,14 @@ sound_source::update_soundproofing() {
|
|||||||
auto const isambient { ( ( m_placement == sound_placement::external ) && ( m_owner == nullptr ) && ( m_range < -1 ) ? 1 : 0 ) };
|
auto const isambient { ( ( m_placement == sound_placement::external ) && ( m_owner == nullptr ) && ( m_range < -1 ) ? 1 : 0 ) };
|
||||||
auto const placement { ( isambient ? sound_placement::external_ambient : m_placement ) };
|
auto const placement { ( isambient ? sound_placement::external_ambient : m_placement ) };
|
||||||
if( m_owner != nullptr ) {
|
if( m_owner != nullptr ) {
|
||||||
m_properties.soundproofing =
|
auto const listenerlocation { (
|
||||||
m_owner->soundproofing(
|
m_owner != listenervehicle ?
|
||||||
static_cast<int>( placement ),
|
4 : // part of two-stage calculation owner->outside->listener, or single stage owner->outside one
|
||||||
( m_owner != listenervehicle ?
|
occupiedcab ) };
|
||||||
4 : // part of two-stage calculation owner->outside->listener, or single stage owner->outside one
|
m_properties.soundproofing = (
|
||||||
occupiedcab ) );
|
m_soundproofing ? // custom soundproofing has higher priority than that of the owner
|
||||||
|
m_soundproofing.value()[ listenerlocation + 1 ] : // cab indices start from -1 so we have to account for this
|
||||||
|
m_owner->soundproofing( static_cast<int>( placement ), listenerlocation ) );
|
||||||
}
|
}
|
||||||
if( ( listenervehicle ) && ( listenervehicle != m_owner ) ) {
|
if( ( listenervehicle ) && ( listenervehicle != m_owner ) ) {
|
||||||
// if the listener is located in another vehicle, calculate additional proofing of the sound coming from outside
|
// if the listener is located in another vehicle, calculate additional proofing of the sound coming from outside
|
||||||
|
|||||||
10
sound.h
10
sound.h
@@ -116,6 +116,11 @@ public:
|
|||||||
start( float const Offset );
|
start( float const Offset );
|
||||||
float const &
|
float const &
|
||||||
start() const;
|
start() const;
|
||||||
|
// custom soundproofing setter/getter
|
||||||
|
auto &
|
||||||
|
soundproofing();
|
||||||
|
auto const &
|
||||||
|
soundproofing() const;
|
||||||
// returns true if there isn't any sound buffer associated with the object, false otherwise
|
// returns true if there isn't any sound buffer associated with the object, false otherwise
|
||||||
bool
|
bool
|
||||||
empty() const;
|
empty() const;
|
||||||
@@ -231,6 +236,7 @@ private:
|
|||||||
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
||||||
bool m_soundchunksempty { true }; // helper, cached check whether sample table is linked with any actual samples
|
bool m_soundchunksempty { true }; // helper, cached check whether sample table is linked with any actual samples
|
||||||
int m_crossfaderange {}; // range of transition from one chunk to another
|
int m_crossfaderange {}; // range of transition from one chunk to another
|
||||||
|
std::optional< std::array<float, 6> > m_soundproofing; // custom soundproofing parameters
|
||||||
};
|
};
|
||||||
|
|
||||||
// owner setter/getter
|
// owner setter/getter
|
||||||
@@ -245,6 +251,10 @@ inline std::string const & sound_source::name() const { return m_name; }
|
|||||||
// playback starting point shift setter/getter
|
// playback starting point shift setter/getter
|
||||||
inline void sound_source::start( float const Offset ) { m_startoffset = Offset; }
|
inline void sound_source::start( float const Offset ) { m_startoffset = Offset; }
|
||||||
inline float const & sound_source::start() const { return m_startoffset; }
|
inline float const & sound_source::start() const { return m_startoffset; }
|
||||||
|
// custom soundproofing setter/getter
|
||||||
|
inline auto & sound_source::soundproofing() { return m_soundproofing; }
|
||||||
|
inline auto const & sound_source::soundproofing() const { return m_soundproofing; }
|
||||||
|
|
||||||
|
|
||||||
// collection of sound sources present in the scene
|
// collection of sound sources present in the scene
|
||||||
class sound_table : public basic_table<sound_source> {
|
class sound_table : public basic_table<sound_source> {
|
||||||
|
|||||||
@@ -393,15 +393,15 @@ init() {
|
|||||||
"Wylaczyc przetwornice",
|
"Wylaczyc przetwornice",
|
||||||
"Odblokowac przekaznik nadmiarowy przetwornicy",
|
"Odblokowac przekaznik nadmiarowy przetwornicy",
|
||||||
"Odblokowac przekaznik roznicowy obwodu glownego",
|
"Odblokowac przekaznik roznicowy obwodu glownego",
|
||||||
"Odblokowac przekaznik nadmiarowy motorow trakcyjnych",
|
"Odblokowac przekaznik nadmiarowy silnikow trakcyjnych",
|
||||||
"Zamknac wylacznik szybki",
|
"Zamknac wylacznik szybki",
|
||||||
"Otworzyc wylacznik szybki",
|
"Otworzyc wylacznik szybki",
|
||||||
"Zalaczyc sprezarke",
|
"Zalaczyc sprezarke",
|
||||||
"Wylaczyc sprezarke",
|
"Wylaczyc sprezarke",
|
||||||
"Zalaczyc wentylatory przednich motorow trakcyjnych",
|
"Zalaczyc wentylatory przednich silnikow trakcyjnych",
|
||||||
"Wylaczyc wentylatory przednich motorow trakcyjnych",
|
"Wylaczyc wentylatory przednich silnikow trakcyjnych",
|
||||||
"Zalaczyc wentylatory tylnych motorow trakcyjnych",
|
"Zalaczyc wentylatory tylnych silnikow trakcyjnych",
|
||||||
"Wylaczyc wentylatory tylnych motorow trakcyjnych",
|
"Wylaczyc wentylatory tylnych silnikow trakcyjnych",
|
||||||
"Zalaczyc hamulec sprezynowy",
|
"Zalaczyc hamulec sprezynowy",
|
||||||
"Zwolnic hamules sprezynowy",
|
"Zwolnic hamules sprezynowy",
|
||||||
"Zalaczyc hamulec reczny",
|
"Zalaczyc hamulec reczny",
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ ui_layer::init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
static ImWchar const glyphranges[] = {
|
static ImWchar const glyphranges[] = {
|
||||||
0x0020, 0x00FF, // ascii + extension
|
0x0020, 0x00FF, // ascii + extension
|
||||||
0x0100, 0x017F, // latin extended-a
|
// 0x0100, 0x017F, // latin extended-a
|
||||||
0x2070, 0x2079, // superscript
|
0x2070, 0x2079, // superscript
|
||||||
0x2500, 0x256C, // box drawings
|
0x2500, 0x256C, // box drawings
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in New Issue
Block a user