16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 18:39:18 +02:00

basic weather-based texture selection, additional control commands, minor line breaker logic fixes

This commit is contained in:
tmj-fstate
2018-02-12 16:19:53 +01:00
parent 6d3ce4908f
commit c75f7138b8
9 changed files with 271 additions and 131 deletions

View File

@@ -5282,34 +5282,46 @@ bool TMoverParameters::AutoRelayCheck(void)
&& ( MainCtrlPos > 0 ) && ( MainCtrlPos > 0 )
&& ( MainCtrlPos != MainCtrlPosNo ) && ( MainCtrlPos != MainCtrlPosNo )
&& ( FastSerialCircuit == 1 ) ) { && ( FastSerialCircuit == 1 ) ) {
// szybkie wchodzenie na bezoporowa (303E)
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
++MainCtrlActualPos; ++MainCtrlActualPos;
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012: if( MainCtrlPos - MainCtrlActualPos == 1 ) {
// szybkie wchodzenie na bezoporowa (303E) // HACK: ensure we play only single sound of basic relays for entire trasition; return false
OK = true; // for all but last step despite configuration change, to prevent playback of the basic relay sound
SetFlag(SoundFlag, sound::parallel | sound::loud); // TBD, TODO: move the basic sound event here and enable it with call parameter
OK = true;
}
if( RList[ MainCtrlActualPos ].R == 0 ) {
SetFlag( SoundFlag, sound::parallel | sound::loud );
OK = true;
}
} }
else if ((LastRelayTime > CtrlDelay) && (ARFASI)) else if ((LastRelayTime > CtrlDelay) && (ARFASI))
{ {
// WriteLog("LRT = " + FloatToStr(LastRelayTime) + ", " + // WriteLog("LRT = " + FloatToStr(LastRelayTime) + ", " +
// FloatToStr(CtrlDelay)); // FloatToStr(CtrlDelay));
if ((TrainType == dt_ET22) && (MainCtrlPos > 1) && if( ( TrainType == dt_ET22 )
((RList[MainCtrlActualPos].Bn < RList[MainCtrlActualPos + 1].Bn) || && ( MainCtrlPos > 1 )
(DelayCtrlFlag))) // et22 z walem grupowym && ( ( RList[ MainCtrlActualPos ].Bn < RList[ MainCtrlActualPos + 1 ].Bn )
if (!DelayCtrlFlag) // najpierw przejscie || ( DelayCtrlFlag ) ) ) {
// et22 z walem grupowym
if( !DelayCtrlFlag ) // najpierw przejscie
{ {
++MainCtrlActualPos; ++MainCtrlActualPos;
DelayCtrlFlag = true; // tryb przejscia DelayCtrlFlag = true; // tryb przejscia
OK = true; OK = true;
} }
else if (LastRelayTime > 4 * CtrlDelay) // przejscie else if( LastRelayTime > 4 * CtrlDelay ) // przejscie
{ {
DelayCtrlFlag = false; DelayCtrlFlag = false;
OK = true; OK = true;
} }
/*
else else
; ;
*/
}
else // nie ET22 z wałem grupowym else // nie ET22 z wałem grupowym
{ {
++MainCtrlActualPos; ++MainCtrlActualPos;
@@ -5317,30 +5329,33 @@ bool TMoverParameters::AutoRelayCheck(void)
} }
//--------- //---------
// hunter-111211: poprawki // hunter-111211: poprawki
if (MainCtrlActualPos > 0) if( MainCtrlActualPos > 0 ) {
if ((RList[MainCtrlActualPos].R == 0) && if( ( RList[ MainCtrlActualPos ].R == 0 )
(!(MainCtrlActualPos == MainCtrlPosNo))) // wejscie na bezoporowa && ( MainCtrlActualPos != MainCtrlPosNo ) ) {
{ // wejscie na bezoporowa
SetFlag(SoundFlag, sound::parallel | sound::loud); SetFlag( SoundFlag, sound::parallel | sound::loud );
} }
else if ((RList[MainCtrlActualPos].R > 0) && else if( ( RList[ MainCtrlActualPos ].R > 0 )
(RList[MainCtrlActualPos - 1].R == && ( RList[ MainCtrlActualPos - 1 ].R == 0 ) ) {
0)) // wejscie na drugi uklad // wejscie na drugi uklad
{ SetFlag( SoundFlag, sound::parallel );
SetFlag(SoundFlag, sound::parallel);
} }
}
} }
} }
else if (RList[MainCtrlActualPos].Relay > MainCtrlPos) else if (RList[MainCtrlActualPos].Relay > MainCtrlPos)
{ {
if ((RList[MainCtrlPos].R == 0) && (MainCtrlPos > 0) && if( ( RList[ MainCtrlPos ].R == 0 )
(!(MainCtrlPos == MainCtrlPosNo)) && (FastSerialCircuit == 1)) && ( MainCtrlPos > 0 )
{ && ( !( MainCtrlPos == MainCtrlPosNo ) )
&& ( FastSerialCircuit == 1 ) ) {
// szybkie wchodzenie na bezoporowa (303E)
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
--MainCtrlActualPos; --MainCtrlActualPos;
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
// szybkie wchodzenie na bezoporowa (303E)
OK = true; OK = true;
SetFlag(SoundFlag, sound::parallel); if( RList[ MainCtrlActualPos ].R == 0 ) {
SetFlag( SoundFlag, sound::parallel );
}
} }
else if (LastRelayTime > CtrlDownDelay) else if (LastRelayTime > CtrlDownDelay)
{ {

289
Train.cpp
View File

@@ -250,7 +250,11 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::headlightenableupper, &TTrain::OnCommand_headlightenableupper }, { user_command::headlightenableupper, &TTrain::OnCommand_headlightenableupper },
{ user_command::headlightdisableupper, &TTrain::OnCommand_headlightdisableupper }, { user_command::headlightdisableupper, &TTrain::OnCommand_headlightdisableupper },
{ user_command::redmarkertoggleleft, &TTrain::OnCommand_redmarkertoggleleft }, { user_command::redmarkertoggleleft, &TTrain::OnCommand_redmarkertoggleleft },
{ user_command::redmarkerenableleft, &TTrain::OnCommand_redmarkerenableleft },
{ user_command::redmarkerdisableleft, &TTrain::OnCommand_redmarkerdisableleft },
{ user_command::redmarkertoggleright, &TTrain::OnCommand_redmarkertoggleright }, { user_command::redmarkertoggleright, &TTrain::OnCommand_redmarkertoggleright },
{ user_command::redmarkerenableright, &TTrain::OnCommand_redmarkerenableright },
{ user_command::redmarkerdisableright, &TTrain::OnCommand_redmarkerdisableright },
{ user_command::headlighttogglerearleft, &TTrain::OnCommand_headlighttogglerearleft }, { user_command::headlighttogglerearleft, &TTrain::OnCommand_headlighttogglerearleft },
{ user_command::headlighttogglerearright, &TTrain::OnCommand_headlighttogglerearright }, { user_command::headlighttogglerearright, &TTrain::OnCommand_headlighttogglerearright },
{ user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper }, { user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper },
@@ -1791,7 +1795,7 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// press or hold... // press or hold...
if( Train->m_linebreakerstate == 0 ) { if( Train->m_linebreakerstate == 0 ) {
// ...to close the circuit // ...to close the circuit
@@ -1803,24 +1807,28 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
OnCommand_linebreakeropen( Train, Command ); OnCommand_linebreakeropen( Train, Command );
} }
} }
else { else if( Command.action == GLFW_RELEASE ) {
// release... // release...
if( Train->m_linebreakerstate <= 0 ) { if( ( Train->ggMainOnButton.SubModel != nullptr )
// ...after opening circuit, or holding for too short time to close it || ( Train->mvControlled->TrainType == dt_EZT ) ) {
OnCommand_linebreakeropen( Train, Command ); // only impulse switches react to release events; since we don't have switch type definition for the line breaker,
} // we detect it from presence of relevant button, or presume such switch arrangement for EMUs
else { if( Train->m_linebreakerstate == 0 ) {
// ...after closing the circuit // ...after opening circuit, or holding for too short time to close it
// NOTE: bit of a dirty shortcut here OnCommand_linebreakeropen( Train, Command );
OnCommand_linebreakerclose( Train, Command ); }
else {
// ...after closing the circuit
// NOTE: bit of a dirty shortcut here
OnCommand_linebreakerclose( Train, Command );
}
} }
} }
} }
void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// press or hold...
// visual feedback // visual feedback
if( Train->ggMainOffButton.SubModel != nullptr ) { if( Train->ggMainOffButton.SubModel != nullptr ) {
// two separate switches to close and break the circuit // two separate switches to close and break the circuit
@@ -1838,6 +1846,10 @@ void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Comma
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
} }
else {
// fallback for cabs with no submodel
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
}
// play sound immediately when the switch is hit, not after release // play sound immediately when the switch is hit, not after release
Train->fMainRelayTimer = 0.0f; Train->fMainRelayTimer = 0.0f;
@@ -1851,11 +1863,11 @@ void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Comma
} }
if( true == Train->mvControlled->MainSwitch( false ) ) { if( true == Train->mvControlled->MainSwitch( false ) ) {
Train->m_linebreakerstate = -1; Train->m_linebreakerstate = 0;
} }
} }
else { else if( Command.action == GLFW_RELEASE ) {
// release... // visual feedback
// we don't exactly know which of the two buttons was used, so reset both // we don't exactly know which of the two buttons was used, so reset both
// for setup with two separate swiches // for setup with two separate swiches
if( Train->ggMainOnButton.SubModel != nullptr ) { if( Train->ggMainOnButton.SubModel != nullptr ) {
@@ -1866,22 +1878,14 @@ void TTrain::OnCommand_linebreakeropen( TTrain *Train, command_data const &Comma
} }
// and the two-state switch too, for good measure // and the two-state switch too, for good measure
if( Train->ggMainButton.SubModel != nullptr ) { if( Train->ggMainButton.SubModel != nullptr ) {
// visual feedback
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
if( Train->m_linebreakerstate < 0 ) {
// finalize state change of the line breaker
Train->m_linebreakerstate = 0;
}
// on button release reset the closing timer
Train->fMainRelayTimer = 0.0f;
} }
} }
void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// press...
// visual feedback // visual feedback
if( Train->ggMainOnButton.SubModel != nullptr ) { if( Train->ggMainOnButton.SubModel != nullptr ) {
// two separate switches to close and break the circuit // two separate switches to close and break the circuit
@@ -1891,10 +1895,14 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
// single two-state switch // single two-state switch
Train->ggMainButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggMainButton.UpdateValue( 1.0, Train->dsbSwitch );
} }
else {
// fallback for cabs with no submodel
Train->ggMainButton.UpdateValue( 1.0, Train->dsbSwitch );
}
// the actual closing of the line breaker is handled in the train update routine // the actual closing of the line breaker is handled in the train update routine
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// release...
// visual feedback // visual feedback
if( Train->ggMainOnButton.SubModel != nullptr ) { if( Train->ggMainOnButton.SubModel != nullptr ) {
// setup with two separate switches // setup with two separate switches
@@ -1905,7 +1913,6 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
// TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz
if( Train->mvControlled->TrainType == dt_EZT ) { if( Train->mvControlled->TrainType == dt_EZT ) {
if( Train->ggMainButton.SubModel != nullptr ) { if( Train->ggMainButton.SubModel != nullptr ) {
// visual feedback
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
} }
@@ -1913,17 +1920,17 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
if( Train->m_linebreakerstate == 1 ) { return; } // already in the desired state if( Train->m_linebreakerstate == 1 ) { return; } // already in the desired state
if( Train->m_linebreakerstate > 1 ) { if( Train->m_linebreakerstate > 1 ) {
// we don't need to start the diesel twice, but the other types still need to be launched // we don't need to start the diesel twice, but the other types (with impulse switch setup) still need to be launched
if( ( Train->mvControlled->EngineType != DieselEngine ) if( ( Train->mvControlled->EngineType != DieselEngine )
&& ( Train->mvControlled->EngineType != DieselElectric ) ) { && ( Train->mvControlled->EngineType != DieselElectric ) ) {
if( Train->mvControlled->MainSwitch( true ) ) { if( Train->mvControlled->MainSwitch( true ) ) {
// side-effects // side-effects
Train->mvControlled->ConverterSwitch( ( Train->ggConverterButton.GetValue() > 0.5 ) || ( Train->mvControlled->ConverterStart == start::automatic ) ); Train->mvControlled->ConverterSwitch( ( Train->ggConverterButton.GetValue() > 0.5 ) || ( Train->mvControlled->ConverterStart == start::automatic ) );
Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 );
// finalize state change of the line breaker
Train->m_linebreakerstate = 1;
} }
} }
// finalize state change of the line breaker
Train->m_linebreakerstate = 1;
} }
// on button release reset the closing timer // on button release reset the closing timer
Train->fMainRelayTimer = 0.0f; Train->fMainRelayTimer = 0.0f;
@@ -2606,90 +2613,160 @@ void TTrain::OnCommand_headlightdisableupper( TTrain *Train, command_data const
void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
int const vehicleside =
( Train->mvOccupied->ActiveCab == 1 ?
side::front :
side::rear );
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) == 0 ) {
// turn on
OnCommand_redmarkerenableleft( Train, Command );
}
else {
//turn off
OnCommand_redmarkerdisableleft( Train, Command );
}
}
}
void TTrain::OnCommand_redmarkerenableleft( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo > 0 ) { if( Train->mvOccupied->LightsPosNo > 0 ) {
// lights are controlled by preset selector // lights are controlled by preset selector
return; return;
} }
int const vehicleside = if( Command.action == GLFW_PRESS ) {
( Train->mvOccupied->ActiveCab == 1 ? // only reacting to press, so the switch doesn't flip back and forth if key is held down
side::front : int const vehicleside =
side::rear ); ( Train->mvOccupied->ActiveCab == 1 ?
side::front :
side::rear );
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) != 0 ) { return; } // already enabled
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left;
// visual feedback
if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_left;
}
}
}
void TTrain::OnCommand_redmarkerdisableleft( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo > 0 ) {
// lights are controlled by preset selector
return;
}
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) == 0 ) { int const vehicleside =
// turn on ( Train->mvOccupied->ActiveCab == 1 ?
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; side::front :
// visual feedback side::rear );
if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) == 0 ) { return; } // already disabled
}
else { Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left;
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch // visual feedback
// this is crude, but for now will do if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftLightButton.UpdateValue( -1.0, Train->dsbSwitch ); Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_left;
}
} }
else { else {
//turn off // we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; // this is crude, but for now will do
// visual feedback Train->ggLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch );
if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
} }
} }
} }
void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
int const vehicleside =
( Train->mvOccupied->ActiveCab == 1 ?
side::front :
side::rear );
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) == 0 ) {
// turn on
OnCommand_redmarkerenableright( Train, Command );
}
else {
//turn off
OnCommand_redmarkerdisableright( Train, Command );
}
}
}
void TTrain::OnCommand_redmarkerenableright( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo > 0 ) { if( Train->mvOccupied->LightsPosNo > 0 ) {
// lights are controlled by preset selector // lights are controlled by preset selector
return; return;
} }
int const vehicleside = if( Command.action == GLFW_PRESS ) {
( Train->mvOccupied->ActiveCab == 1 ? // only reacting to press, so the switch doesn't flip back and forth if key is held down
side::front : int const vehicleside =
side::rear ); ( Train->mvOccupied->ActiveCab == 1 ?
side::front :
side::rear );
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) != 0 ) { return; } // already enabled
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right;
// visual feedback
if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_right;
}
}
}
void TTrain::OnCommand_redmarkerdisableright( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo > 0 ) {
// lights are controlled by preset selector
return;
}
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) == 0 ) { int const vehicleside =
// turn on ( Train->mvOccupied->ActiveCab == 1 ?
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; side::front :
// visual feedback side::rear );
if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) == 0 ) { return; } // already disabled
}
else { Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right;
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch // visual feedback
// this is crude, but for now will do if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightLightButton.UpdateValue( -1.0, Train->dsbSwitch ); Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_right;
}
} }
else { else {
//turn off // we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; // this is crude, but for now will do
// visual feedback Train->ggRightLightButton.UpdateValue( 0.0, Train->dsbSwitch );
if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
} }
} }
} }
@@ -3697,6 +3774,7 @@ bool TTrain::Update( double const Deltatime )
m_linebreakerstate = 0; m_linebreakerstate = 0;
} }
} }
if( ( ggMainButton.GetDesiredValue() > 0.95 ) if( ( ggMainButton.GetDesiredValue() > 0.95 )
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) { || ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) {
// keep track of period the line breaker button is held down, to determine when/if circuit closes // keep track of period the line breaker button is held down, to determine when/if circuit closes
@@ -3708,23 +3786,6 @@ bool TTrain::Update( double const Deltatime )
// TODO: consider whether it makes sense for diesel engines and such // TODO: consider whether it makes sense for diesel engines and such
fMainRelayTimer += Deltatime; fMainRelayTimer += Deltatime;
} }
if( m_linebreakerstate < 1 ) {
if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) {
// wlaczanie WSa z opoznieniem
m_linebreakerstate = 2;
// for diesels, we complete the engine start here
// TODO: consider arranging a better way to start the diesel engines
if( ( mvControlled->EngineType == DieselEngine )
|| ( mvControlled->EngineType == DieselElectric ) ) {
if( mvControlled->MainSwitch( true ) ) {
// side-effects
mvControlled->ConverterSwitch( ( ggConverterButton.GetDesiredValue() > 0.95 ) || ( mvControlled->ConverterStart == start::automatic ) );
mvControlled->CompressorSwitch( ggCompressorButton.GetDesiredValue() > 0.95 );
}
}
}
}
} }
else { else {
// button isn't down, reset the timer // button isn't down, reset the timer
@@ -3734,6 +3795,28 @@ bool TTrain::Update( double const Deltatime )
// if the button disconnecting the line breaker is down prevent the timer from accumulating // if the button disconnecting the line breaker is down prevent the timer from accumulating
fMainRelayTimer = 0.0f; fMainRelayTimer = 0.0f;
} }
if( m_linebreakerstate == 0 ) {
if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) {
// wlaczanie WSa z opoznieniem
// mark the line breaker as ready to close; for electric vehicles with impulse switch the setup is completed on button release
m_linebreakerstate = 2;
}
}
if( m_linebreakerstate == 2 ) {
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
// TBD, TODO: arrange a better way to start the diesel engines
if( ( ggMainOffButton.SubModel == nullptr )
|| ( ( mvControlled->EngineType == DieselEngine )
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
if( mvControlled->MainSwitch( true ) ) {
// side-effects
mvControlled->ConverterSwitch( ( ggConverterButton.GetDesiredValue() > 0.95 ) || ( mvControlled->ConverterStart == start::automatic ) );
mvControlled->CompressorSwitch( ggCompressorButton.GetDesiredValue() > 0.95 );
// finalize state change of the line breaker
m_linebreakerstate = 1;
}
}
}
// check for received user commands // check for received user commands
// NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one // NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one

View File

@@ -240,7 +240,11 @@ class TTrain
static void OnCommand_headlightenableupper( TTrain *Train, command_data const &Command ); static void OnCommand_headlightenableupper( TTrain *Train, command_data const &Command );
static void OnCommand_headlightdisableupper( TTrain *Train, command_data const &Command ); static void OnCommand_headlightdisableupper( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command ); static void OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkerenableleft( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkerdisableleft( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command ); static void OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkerenableright( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkerdisableright( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
@@ -284,7 +288,7 @@ class TTrain
TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia) TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia)
TMoverParameters *mvThird; // trzeci człon (SN61) TMoverParameters *mvThird; // trzeci człon (SN61)
// helper variable, to prevent immediate switch between closing and opening line breaker circuit // helper variable, to prevent immediate switch between closing and opening line breaker circuit
int m_linebreakerstate { 0 }; // -1: freshly open, 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it) int m_linebreakerstate { 0 }; // 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
static const commandhandler_map m_commandhandlers; static const commandhandler_map m_commandhandlers;
control_mapper m_controlmapper; control_mapper m_controlmapper;
@@ -577,7 +581,7 @@ private:
float fPress[20][3]; // cisnienia dla wszystkich czlonow float fPress[20][3]; // cisnienia dla wszystkich czlonow
static std::vector<std::string> const fPress_labels; static std::vector<std::string> const fPress_labels;
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
int RadioChannel() { return iRadioChannel; }; int RadioChannel() const { return iRadioChannel; };
// plays provided sound from position of the radio // plays provided sound from position of the radio
void radio_message( sound_source *Message, int const Channel ); void radio_message( sound_source *Message, int const Channel );
inline TDynamicObject *Dynamic() { return DynamicObject; }; inline TDynamicObject *Dynamic() { return DynamicObject; };

View File

@@ -1317,6 +1317,11 @@ TWorld::Update_UI() {
uitextline2 += ( vehicle->MoverParameters->ConvOvldFlag ? "!" : "." ); uitextline2 += ( vehicle->MoverParameters->ConvOvldFlag ? "!" : "." );
uitextline2 += ( false == vehicle->MoverParameters->CompressorAllowLocal ? "-" : ( ( vehicle->MoverParameters->CompressorAllow || vehicle->MoverParameters->CompressorPower > 1 ) ? ( vehicle->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) ); uitextline2 += ( false == vehicle->MoverParameters->CompressorAllowLocal ? "-" : ( ( vehicle->MoverParameters->CompressorAllow || vehicle->MoverParameters->CompressorPower > 1 ) ? ( vehicle->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) );
uitextline2 += ( vehicle->MoverParameters->CompressorGovernorLock ? "!" : "." ); uitextline2 += ( vehicle->MoverParameters->CompressorGovernorLock ? "!" : "." );
auto const train { Global.pWorld->train() };
if( ( train != nullptr ) && ( train->Dynamic() == vehicle ) ) {
uitextline2 += " R: " + std::to_string( train->RadioChannel() );
}
/* /*
uitextline2 += uitextline2 +=
" AnlgB: " + to_string( tmp->MoverParameters->AnPos, 1 ) " AnlgB: " + to_string( tmp->MoverParameters->AnPos, 1 )
@@ -2124,9 +2129,21 @@ TWorld::compute_season( int const Yearday ) const {
return Left.first < Right; } ); return Left.first < Right; } );
Global.Season = lookup->second + ":"; Global.Season = lookup->second + ":";
// season can affect the weather so if it changes, re-calculate weather as well
compute_weather();
} }
// calculates current weather
void
TWorld::compute_weather() const {
Global.Weather = (
Global.Overcast < 0.25 ? "clear:" :
Global.Overcast < 1.0 ? "cloudy:" :
( Global.Season != "winter:" ?
"rain:" :
"snow:" ) );
}
void void
world_environment::init() { world_environment::init() {

View File

@@ -110,6 +110,8 @@ TWorld();
void ToggleDaylight(); void ToggleDaylight();
// calculates current season of the year based on set simulation date // calculates current season of the year based on set simulation date
void compute_season( int const Yearday ) const; void compute_season( int const Yearday ) const;
// calculates current weather
void compute_weather() const;
// members // members

View File

@@ -140,7 +140,11 @@ commanddescription_sequence Commands_descriptions = {
{ "headlightenableupper", command_target::vehicle }, { "headlightenableupper", command_target::vehicle },
{ "headlightdisableupper", command_target::vehicle }, { "headlightdisableupper", command_target::vehicle },
{ "redmarkertoggleleft", command_target::vehicle }, { "redmarkertoggleleft", command_target::vehicle },
{ "redmarkerenableleft", command_target::vehicle },
{ "redmarkerdisableleft", command_target::vehicle },
{ "redmarkertoggleright", command_target::vehicle }, { "redmarkertoggleright", command_target::vehicle },
{ "redmarkerenableright", command_target::vehicle },
{ "redmarkerdisableright", command_target::vehicle },
{ "headlighttogglerearleft", command_target::vehicle }, { "headlighttogglerearleft", command_target::vehicle },
{ "headlighttogglerearright", command_target::vehicle }, { "headlighttogglerearright", command_target::vehicle },
{ "headlighttogglerearupper", command_target::vehicle }, { "headlighttogglerearupper", command_target::vehicle },

View File

@@ -133,7 +133,11 @@ enum class user_command {
headlightenableupper, headlightenableupper,
headlightdisableupper, headlightdisableupper,
redmarkertoggleleft, redmarkertoggleleft,
redmarkerenableleft,
redmarkerdisableleft,
redmarkertoggleright, redmarkertoggleright,
redmarkerenableright,
redmarkerdisableright,
headlighttogglerearleft, headlighttogglerearleft,
headlighttogglerearright, headlighttogglerearright,
headlighttogglerearupper, headlighttogglerearupper,

View File

@@ -403,8 +403,16 @@ keyboard_input::default_bindings() {
{ -1 }, { -1 },
// redmarkertoggleleft // redmarkertoggleleft
{ GLFW_KEY_Y | keymodifier::shift }, { GLFW_KEY_Y | keymodifier::shift },
// redmarkerenableleft
{ -1 },
// redmarkerdisableleft
{ -1 },
// redmarkertoggleright // redmarkertoggleright
{ GLFW_KEY_I | keymodifier::shift }, { GLFW_KEY_I | keymodifier::shift },
// redmarkerenableright
{ -1 },
// redmarkerdisableright
{ -1 },
// headlighttogglerearleft // headlighttogglerearleft
{ GLFW_KEY_Y | keymodifier::control }, { GLFW_KEY_Y | keymodifier::control },
// headlighttogglerearright // headlighttogglerearright

View File

@@ -167,6 +167,9 @@ state_manager::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad
if( token != "endatmo" ) { if( token != "endatmo" ) {
// optional overcast parameter // optional overcast parameter
Global.Overcast = clamp( std::stof( token ), 0.f, 2.f ); Global.Overcast = clamp( std::stof( token ), 0.f, 2.f );
// overcast drives weather so do a calculation here
// NOTE: ugly, clean it up when we're done with world refactoring
Global.pWorld->compute_weather();
} }
while( ( false == token.empty() ) while( ( false == token.empty() )
&& ( token != "endatmo" ) ) { && ( token != "endatmo" ) ) {