mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 05:49:19 +02:00
build 200126. memory cell-based simulation state interface , time of day slider, minor bug fixes
This commit is contained in:
@@ -81,6 +81,7 @@ struct global_settings {
|
|||||||
float fFogEnd{ 7500 };
|
float fFogEnd{ 7500 };
|
||||||
std::string Season{}; // season of the year, based on simulation date
|
std::string Season{}; // season of the year, based on simulation date
|
||||||
std::string Weather{ "cloudy:" }; // current weather
|
std::string Weather{ "cloudy:" }; // current weather
|
||||||
|
std::string Period{}; // time of the day, based on sun position
|
||||||
bool FullPhysics{ true }; // full calculations performed for each simulation step
|
bool FullPhysics{ true }; // full calculations performed for each simulation step
|
||||||
bool bnewAirCouplers{ true };
|
bool bnewAirCouplers{ true };
|
||||||
float fMoveLight{ -1.f }; // numer dnia w roku albo -1
|
float fMoveLight{ -1.f }; // numer dnia w roku albo -1
|
||||||
|
|||||||
@@ -1381,6 +1381,7 @@ public:
|
|||||||
double MainsInitTime{ 0.0 }; // config, initialization time (in seconds) of the main circuit after it receives power, before it can be closed
|
double MainsInitTime{ 0.0 }; // config, initialization time (in seconds) of the main circuit after it receives power, before it can be closed
|
||||||
double MainsInitTimeCountdown{ 0.0 }; // current state of main circuit initialization, remaining time (in seconds) until it's ready
|
double MainsInitTimeCountdown{ 0.0 }; // current state of main circuit initialization, remaining time (in seconds) until it's ready
|
||||||
bool LineBreakerClosesAtNoPowerPosOnly{ false };
|
bool LineBreakerClosesAtNoPowerPosOnly{ false };
|
||||||
|
bool HasPressureSwitch{ true };
|
||||||
int MainCtrlPos = 0; /*polozenie glownego nastawnika*/
|
int MainCtrlPos = 0; /*polozenie glownego nastawnika*/
|
||||||
int ScndCtrlPos = 0; /*polozenie dodatkowego nastawnika*/
|
int ScndCtrlPos = 0; /*polozenie dodatkowego nastawnika*/
|
||||||
int LightsPos = 0; /*polozenie przelacznika wielopozycyjnego swiatel*/
|
int LightsPos = 0; /*polozenie przelacznika wielopozycyjnego swiatel*/
|
||||||
|
|||||||
@@ -6222,9 +6222,8 @@ bool TMoverParameters::AutoRelayCheck(void)
|
|||||||
// main bez samoczynnego rozruchu
|
// main bez samoczynnego rozruchu
|
||||||
if( ( MainCtrlActualPos < ( sizeof( RList ) / sizeof( TScheme ) - 1 ) ) // crude guard against running out of current fixed table
|
if( ( MainCtrlActualPos < ( sizeof( RList ) / sizeof( TScheme ) - 1 ) ) // crude guard against running out of current fixed table
|
||||||
&& ( ( RList[ MainCtrlActualPos ].Relay < MainCtrlPos )
|
&& ( ( RList[ MainCtrlActualPos ].Relay < MainCtrlPos )
|
||||||
|| ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos )
|
|| ( ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos ) && ( MainCtrlActualPos < RlistSize ) )
|
||||||
|| ( ( TrainType == dt_ET22 )
|
|| ( ( TrainType == dt_ET22 ) && ( DelayCtrlFlag ) ) ) ) {
|
||||||
&& ( DelayCtrlFlag ) ) ) ) {
|
|
||||||
|
|
||||||
if( ( RList[MainCtrlPos].R == 0 )
|
if( ( RList[MainCtrlPos].R == 0 )
|
||||||
&& ( MainCtrlPos > 0 )
|
&& ( MainCtrlPos > 0 )
|
||||||
@@ -6359,7 +6358,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
|||||||
&& ( ( MainCtrlActualPos > 0 )
|
&& ( ( MainCtrlActualPos > 0 )
|
||||||
|| ( ScndCtrlActualPos > 0 ) ) ) {
|
|| ( ScndCtrlActualPos > 0 ) ) ) {
|
||||||
|
|
||||||
if( CoupledCtrl || HasCamshaft ) {
|
if( CoupledCtrl ) {
|
||||||
|
|
||||||
if( TrainType == dt_EZT ) {
|
if( TrainType == dt_EZT ) {
|
||||||
// EN57 wal jednokierunkowy calosciowy
|
// EN57 wal jednokierunkowy calosciowy
|
||||||
@@ -6393,8 +6392,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
|||||||
else {
|
else {
|
||||||
// wal kulakowy dwukierunkowy
|
// wal kulakowy dwukierunkowy
|
||||||
if( LastRelayTime > CtrlDownDelay ) {
|
if( LastRelayTime > CtrlDownDelay ) {
|
||||||
if( ( CoupledCtrl )
|
if( ScndCtrlActualPos > 0 ) {
|
||||||
&& ( ScndCtrlActualPos > 0 ) ) {
|
|
||||||
--ScndCtrlActualPos;
|
--ScndCtrlActualPos;
|
||||||
SetFlag( SoundFlag, sound::shuntfield );
|
SetFlag( SoundFlag, sound::shuntfield );
|
||||||
}
|
}
|
||||||
@@ -6405,6 +6403,16 @@ bool TMoverParameters::AutoRelayCheck(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( HasCamshaft ) {
|
||||||
|
// wal kulakowy dwukierunkowy
|
||||||
|
if( LastRelayTime > CtrlDownDelay ) {
|
||||||
|
if( MainCtrlActualPos > 0 ) {
|
||||||
|
--MainCtrlActualPos;
|
||||||
|
}
|
||||||
|
ScndCtrlActualPos = 0;
|
||||||
|
OK = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
MainCtrlActualPos = 0;
|
MainCtrlActualPos = 0;
|
||||||
ScndCtrlActualPos = 0;
|
ScndCtrlActualPos = 0;
|
||||||
@@ -6424,6 +6432,7 @@ bool TMoverParameters::MotorConnectorsCheck() {
|
|||||||
// hunter-111211: wylacznik cisnieniowy
|
// hunter-111211: wylacznik cisnieniowy
|
||||||
auto const pressureswitch {
|
auto const pressureswitch {
|
||||||
( TrainType != dt_EZT )
|
( TrainType != dt_EZT )
|
||||||
|
&& ( HasPressureSwitch )
|
||||||
&& ( ( BrakePress > 2.0 )
|
&& ( ( BrakePress > 2.0 )
|
||||||
|| ( PipePress < 3.6 ) ) };
|
|| ( PipePress < 3.6 ) ) };
|
||||||
|
|
||||||
@@ -10090,6 +10099,8 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
// traction motors
|
// traction motors
|
||||||
extract_value( MotorBlowers[ end::front ].speed, "MotorBlowersSpeed", Input, "" );
|
extract_value( MotorBlowers[ end::front ].speed, "MotorBlowersSpeed", Input, "" );
|
||||||
MotorBlowers[ end::rear ] = MotorBlowers[ end::front ];
|
MotorBlowers[ end::rear ] = MotorBlowers[ end::front ];
|
||||||
|
// pressure switch
|
||||||
|
extract_value( HasPressureSwitch, "PressureSwitch", Input, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
||||||
|
|||||||
66
Train.cpp
66
Train.cpp
@@ -249,6 +249,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
|||||||
{ user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall },
|
{ user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall },
|
||||||
{ user_command::pantographselectnext, &TTrain::OnCommand_pantographselectnext },
|
{ user_command::pantographselectnext, &TTrain::OnCommand_pantographselectnext },
|
||||||
{ user_command::pantographselectprevious, &TTrain::OnCommand_pantographselectprevious },
|
{ user_command::pantographselectprevious, &TTrain::OnCommand_pantographselectprevious },
|
||||||
|
{ user_command::pantographtoggleselected, &TTrain::OnCommand_pantographtoggleselected },
|
||||||
{ user_command::pantographraiseselected, &TTrain::OnCommand_pantographraiseselected },
|
{ user_command::pantographraiseselected, &TTrain::OnCommand_pantographraiseselected },
|
||||||
{ user_command::pantographlowerselected, &TTrain::OnCommand_pantographlowerselected },
|
{ user_command::pantographlowerselected, &TTrain::OnCommand_pantographlowerselected },
|
||||||
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
|
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
|
||||||
@@ -2224,6 +2225,37 @@ void TTrain::OnCommand_pantographselectprevious( TTrain *Train, command_data con
|
|||||||
Train->change_pantograph_selection( -1 );
|
Train->change_pantograph_selection( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_pantographtoggleselected( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_REPEAT ) { return; }
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||||
|
auto const state {
|
||||||
|
Train->mvControlled->PantsValve.is_enabled
|
||||||
|
| Train->mvControlled->PantsValve.is_active }; // fallback for impulse switches
|
||||||
|
if( state ) {
|
||||||
|
OnCommand_pantographlowerselected( Train, Command );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OnCommand_pantographraiseselected( Train, Command );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
// impulse switches return automatically to neutral position
|
||||||
|
if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) {
|
||||||
|
Train->mvControlled->OperatePantographsValve( operation_t::enable_off );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
if( Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ) {
|
||||||
|
Train->mvControlled->OperatePantographsValve( operation_t::disable_off );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( Command.action == GLFW_REPEAT ) { return; }
|
if( Command.action == GLFW_REPEAT ) { return; }
|
||||||
@@ -2231,18 +2263,15 @@ void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data cons
|
|||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// raise selected
|
// raise selected
|
||||||
Train->mvControlled->OperatePantographsValve(
|
Train->mvControlled->OperatePantographsValve(
|
||||||
Train->ggPantSelectedButton.type() == TGaugeType::toggle ?
|
Train->ggPantSelectedButton.type() != TGaugeType::toggle ?
|
||||||
operation_t::enable :
|
operation_t::enable_on :
|
||||||
operation_t::enable_on );
|
operation_t::enable );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) {
|
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
|
||||||
Train->mvControlled->OperatePantographsValve( operation_t::enable_off );
|
OnCommand_pantographtoggleselected( Train, Command );
|
||||||
// visual feedback
|
|
||||||
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2253,18 +2282,18 @@ void TTrain::OnCommand_pantographlowerselected( TTrain *Train, command_data cons
|
|||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// lower selected
|
// lower selected
|
||||||
Train->mvControlled->OperatePantographsValve(
|
Train->mvControlled->OperatePantographsValve(
|
||||||
Train->ggPantSelectedDownButton.type() == TGaugeType::toggle ?
|
Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ?
|
||||||
operation_t::disable :
|
operation_t::disable_on :
|
||||||
operation_t::disable_on );
|
operation_t::disable );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
if( Train->ggPantSelectedButton.type() == TGaugeType::toggle ) {
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
if( Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ) {
|
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
|
||||||
Train->mvControlled->OperatePantographsValve( operation_t::disable_off );
|
OnCommand_pantographtoggleselected( Train, Command );
|
||||||
// visual feedback
|
|
||||||
Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5682,7 +5711,8 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
&& ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
||||||
// nie blokujemy AI
|
// nie blokujemy AI
|
||||||
if( ( mvOccupied->TrainType == dt_ET40 )
|
if( ( mvOccupied->TrainType == dt_ET40 )
|
||||||
|| ( mvOccupied->TrainType == dt_EP05 ) ) {
|
|| ( mvOccupied->TrainType == dt_EP05 )
|
||||||
|
|| ( mvOccupied->HasCamshaft ) ) {
|
||||||
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
||||||
// TODO: use deltatime to stabilize speed
|
// TODO: use deltatime to stabilize speed
|
||||||
/*
|
/*
|
||||||
@@ -5691,7 +5721,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
|| ( input::command == user_command::mastercontrollerincrease )
|
|| ( input::command == user_command::mastercontrollerincrease )
|
||||||
|| ( input::command == user_command::mastercontrollerdecrease ) ) ) {
|
|| ( input::command == user_command::mastercontrollerdecrease ) ) ) {
|
||||||
*/
|
*/
|
||||||
if( false == m_mastercontrollerinuse ) {
|
if( false == ( m_mastercontrollerinuse || Global.ctrlState ) ) {
|
||||||
m_mastercontrollerreturndelay -= Deltatime;
|
m_mastercontrollerreturndelay -= Deltatime;
|
||||||
if( m_mastercontrollerreturndelay < 0.f ) {
|
if( m_mastercontrollerreturndelay < 0.f ) {
|
||||||
m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY;
|
m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY;
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -257,6 +257,7 @@ class TTrain {
|
|||||||
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
|
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_pantographselectnext( TTrain *Train, command_data const &Command );
|
static void OnCommand_pantographselectnext( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command );
|
static void OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_pantographtoggleselected( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command );
|
static void OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command );
|
static void OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
|
||||||
|
|||||||
@@ -255,6 +255,14 @@ eu07_application::set_progress( float const Progress, float const Subtaskprogres
|
|||||||
m_modes[ m_modestack.top() ]->set_progress( Progress, Subtaskprogress );
|
m_modes[ m_modestack.top() ]->set_progress( Progress, Subtaskprogress );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::set_tooltip( std::string const &Tooltip ) {
|
||||||
|
|
||||||
|
if( m_modestack.empty() ) { return; }
|
||||||
|
|
||||||
|
m_modes[ m_modestack.top() ]->set_tooltip( Tooltip );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eu07_application::set_cursor( int const Mode ) {
|
eu07_application::set_cursor( int const Mode ) {
|
||||||
|
|
||||||
@@ -288,7 +296,16 @@ eu07_application::get_mouse_button( int const Button ) const {
|
|||||||
|
|
||||||
return glfwGetMouseButton( m_windows.front(), Button );
|
return glfwGetMouseButton( m_windows.front(), Button );
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// provides keyboard mapping associated with specified control item
|
||||||
|
std::string
|
||||||
|
eu07_application::get_input_hint( user_command const Command ) const {
|
||||||
|
|
||||||
|
if( m_modestack.empty() ) { return ""; }
|
||||||
|
|
||||||
|
return m_modes[ m_modestack.top() ]->get_input_hint( Command );
|
||||||
|
}
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
eu07_application::on_key( int const Key, int const Scancode, int const Action, int const Mods ) {
|
eu07_application::on_key( int const Key, int const Scancode, int const Action, int const Mods ) {
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public:
|
|||||||
set_title( std::string const &Title );
|
set_title( std::string const &Title );
|
||||||
void
|
void
|
||||||
set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f );
|
set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f );
|
||||||
|
void
|
||||||
|
set_tooltip( std::string const &Tooltip );
|
||||||
void
|
void
|
||||||
set_cursor( int const Mode );
|
set_cursor( int const Mode );
|
||||||
void
|
void
|
||||||
@@ -62,6 +64,11 @@ public:
|
|||||||
get_cursor_pos( double &Horizontal, double &Vertical ) const;
|
get_cursor_pos( double &Horizontal, double &Vertical ) const;
|
||||||
int
|
int
|
||||||
get_mouse_button( int const Button ) const;
|
get_mouse_button( int const Button ) const;
|
||||||
|
/*
|
||||||
|
// provides inputs associated with specified command
|
||||||
|
std::string
|
||||||
|
get_input_hint( user_command const Command ) const;
|
||||||
|
*/
|
||||||
// input handlers
|
// input handlers
|
||||||
void
|
void
|
||||||
on_key( int const Key, int const Scancode, int const Action, int const Mods );
|
on_key( int const Key, int const Scancode, int const Action, int const Mods );
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "pantographlowerall", command_target::vehicle },
|
{ "pantographlowerall", command_target::vehicle },
|
||||||
{ "pantographselectnext", command_target::vehicle },
|
{ "pantographselectnext", command_target::vehicle },
|
||||||
{ "pantographselectprevious", command_target::vehicle },
|
{ "pantographselectprevious", command_target::vehicle },
|
||||||
|
{ "pantographtoggleselected", command_target::vehicle },
|
||||||
{ "pantographraiseselected", command_target::vehicle },
|
{ "pantographraiseselected", command_target::vehicle },
|
||||||
{ "pantographlowerselected", command_target::vehicle },
|
{ "pantographlowerselected", command_target::vehicle },
|
||||||
{ "heatingtoggle", command_target::vehicle },
|
{ "heatingtoggle", command_target::vehicle },
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ enum class user_command {
|
|||||||
pantographlowerall,
|
pantographlowerall,
|
||||||
pantographselectnext,
|
pantographselectnext,
|
||||||
pantographselectprevious,
|
pantographselectprevious,
|
||||||
|
pantographtoggleselected,
|
||||||
pantographraiseselected,
|
pantographraiseselected,
|
||||||
pantographlowerselected,
|
pantographlowerselected,
|
||||||
heatingtoggle,
|
heatingtoggle,
|
||||||
|
|||||||
@@ -182,8 +182,9 @@ driverkeyboard_input::default_bindings() {
|
|||||||
{ user_command::pantographlowerall, GLFW_KEY_P | keymodifier::control },
|
{ user_command::pantographlowerall, GLFW_KEY_P | keymodifier::control },
|
||||||
{ user_command::pantographselectnext, GLFW_KEY_P | keymodifier::shift },
|
{ user_command::pantographselectnext, GLFW_KEY_P | keymodifier::shift },
|
||||||
{ user_command::pantographselectprevious, GLFW_KEY_O | keymodifier::shift },
|
{ user_command::pantographselectprevious, GLFW_KEY_O | keymodifier::shift },
|
||||||
{ user_command::pantographraiseselected, GLFW_KEY_O | keymodifier::shift | keymodifier::control },
|
{ user_command::pantographtoggleselected, GLFW_KEY_O | keymodifier::shift | keymodifier::control },
|
||||||
{ user_command::pantographlowerselected, GLFW_KEY_O | keymodifier::control },
|
// pantographraiseselected,
|
||||||
|
// pantographlowerselected,
|
||||||
{ user_command::heatingtoggle, GLFW_KEY_H },
|
{ user_command::heatingtoggle, GLFW_KEY_H },
|
||||||
// heatingenable,
|
// heatingenable,
|
||||||
// heatingdisable,
|
// heatingdisable,
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ driver_mode::update() {
|
|||||||
simulation::Time.update( deltatime );
|
simulation::Time.update( deltatime );
|
||||||
}
|
}
|
||||||
simulation::State.update_clocks();
|
simulation::State.update_clocks();
|
||||||
|
simulation::State.update_scripting_interface();
|
||||||
simulation::Environment.update();
|
simulation::Environment.update();
|
||||||
|
|
||||||
// fixed step, simulation time based updates
|
// fixed step, simulation time based updates
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ drivermouse_input::default_bindings() {
|
|||||||
user_command::pantographlowerall,
|
user_command::pantographlowerall,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
{ "pantselected_sw:", {
|
{ "pantselected_sw:", {
|
||||||
user_command::pantographraiseselected,
|
user_command::pantographtoggleselected,
|
||||||
user_command::none } }, // TBD: bind lowerselected in case of toggle switch
|
user_command::none } }, // TBD: bind lowerselected in case of toggle switch
|
||||||
{ "pantselectedoff_sw:", {
|
{ "pantselectedoff_sw:", {
|
||||||
user_command::pantographlowerselected,
|
user_command::pantographlowerselected,
|
||||||
|
|||||||
@@ -542,31 +542,7 @@ debug_panel::render() {
|
|||||||
render_section( "Vehicle Engine", m_enginelines );
|
render_section( "Vehicle Engine", m_enginelines );
|
||||||
render_section( "Vehicle AI", m_ailines );
|
render_section( "Vehicle AI", m_ailines );
|
||||||
render_section( "Vehicle Scan Table", m_scantablelines );
|
render_section( "Vehicle Scan Table", m_scantablelines );
|
||||||
if( true == render_section( "Scenario", m_scenariolines ) ) {
|
render_section_scenario();
|
||||||
// fog slider
|
|
||||||
auto fogrange = std::log( Global.fFogEnd );
|
|
||||||
if( ImGui::SliderFloat(
|
|
||||||
( to_string( std::exp( fogrange ), 0 ) + " m###fogend" ).c_str(), &fogrange, std::log( 10.0f ), std::log( 25000.0f ), "Fog distance" ) ) {
|
|
||||||
Global.fFogEnd = clamp( std::exp( fogrange ), 10.0f, 25000.0f );
|
|
||||||
}
|
|
||||||
// cloud cover slider
|
|
||||||
if( ImGui::SliderFloat(
|
|
||||||
( to_string(Global.Overcast, 2 ) + " (" + Global.Weather + ")###overcast" ).c_str(), &Global.Overcast, 0.0f, 2.0f, "Cloud cover" ) ) {
|
|
||||||
Global.Overcast = clamp( Global.Overcast, 0.0f, 2.0f );
|
|
||||||
simulation::Environment.compute_weather();
|
|
||||||
}
|
|
||||||
// day of year slider
|
|
||||||
if( ImGui::SliderFloat( ( to_string( Global.fMoveLight, 0, 4 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 355.0f, "Day of year" ) ) {
|
|
||||||
Global.fMoveLight = clamp( Global.fMoveLight, 0.0f, 355.0f );
|
|
||||||
auto const weather { Global.Weather };
|
|
||||||
simulation::Environment.compute_season( Global.fMoveLight );
|
|
||||||
simulation::Time.init();
|
|
||||||
if( weather != Global.Weather ) {
|
|
||||||
// HACK: force re-calculation of precipitation
|
|
||||||
Global.Overcast = clamp( Global.Overcast - 0.0001f, 0.0f, 2.0f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) {
|
if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) {
|
||||||
// event queue filter
|
// event queue filter
|
||||||
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
||||||
@@ -584,6 +560,63 @@ debug_panel::render() {
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
debug_panel::render_section_scenario() {
|
||||||
|
|
||||||
|
if( false == render_section( "Scenario", m_scenariolines ) ) { return false; }
|
||||||
|
|
||||||
|
// fog slider
|
||||||
|
{
|
||||||
|
auto fogrange = std::log( Global.fFogEnd );
|
||||||
|
if( ImGui::SliderFloat(
|
||||||
|
( to_string( std::exp( fogrange ), 0, 5 ) + " m###fogend" ).c_str(), &fogrange, std::log( 10.0f ), std::log( 25000.0f ), "Fog distance" ) ) {
|
||||||
|
Global.fFogEnd = clamp( std::exp( fogrange ), 10.0f, 25000.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cloud cover slider
|
||||||
|
{
|
||||||
|
if( ImGui::SliderFloat(
|
||||||
|
( to_string( Global.Overcast, 2, 5 ) + " (" + Global.Weather + ")###overcast" ).c_str(), &Global.Overcast, 0.0f, 2.0f, "Cloud cover" ) ) {
|
||||||
|
Global.Overcast = clamp( Global.Overcast, 0.0f, 2.0f );
|
||||||
|
simulation::Environment.compute_weather();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// day of year slider
|
||||||
|
{
|
||||||
|
if( ImGui::SliderFloat( ( to_string( Global.fMoveLight, 0, 5 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 364.0f, "Day of year" ) ) {
|
||||||
|
Global.fMoveLight = clamp( Global.fMoveLight, 0.0f, 365.0f );
|
||||||
|
auto const weather{ Global.Weather };
|
||||||
|
simulation::Environment.compute_season( Global.fMoveLight );
|
||||||
|
simulation::Time.init();
|
||||||
|
if( weather != Global.Weather ) {
|
||||||
|
// HACK: force re-calculation of precipitation
|
||||||
|
Global.Overcast = clamp( Global.Overcast - 0.0001f, 0.0f, 2.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// time of day slider
|
||||||
|
{
|
||||||
|
ImGui::PushStyleColor( ImGuiCol_Text, { Global.UITextColor.r, Global.UITextColor.g, Global.UITextColor.b, Global.UITextColor.a } );
|
||||||
|
ImGui::TextUnformatted( "CAUTION: time change will affect simulation state" );
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
auto time = simulation::Time.data().wHour * 60 + simulation::Time.data().wMinute;
|
||||||
|
auto const timestring{
|
||||||
|
std::string( to_string( int( 100 + simulation::Time.data().wHour ) ).substr( 1, 2 )
|
||||||
|
+ ":"
|
||||||
|
+ std::string( to_string( int( 100 + simulation::Time.data().wMinute ) ).substr( 1, 2 ) ) ) };
|
||||||
|
if( ImGui::SliderInt( ( timestring + " (" + Global.Period + ")###simulationtime" ).c_str(), &time, 0, 1439, "Time of day" ) ) {
|
||||||
|
time = clamp( time, 0, 1439 );
|
||||||
|
auto const hour{ std::floor( time / 60 ) };
|
||||||
|
auto const minute{ time % 60 };
|
||||||
|
simulation::Time.data().wHour = hour;
|
||||||
|
simulation::Time.data().wMinute = minute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ private:
|
|||||||
std::string update_vehicle_brake() const;
|
std::string update_vehicle_brake() const;
|
||||||
// renders provided lines, under specified collapsing header
|
// renders provided lines, under specified collapsing header
|
||||||
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||||
|
bool render_section_scenario();
|
||||||
// members
|
// members
|
||||||
std::array<char, 1024> m_buffer;
|
std::array<char, 1024> m_buffer;
|
||||||
input_data m_input;
|
input_data m_input;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "AnimModel.h"
|
#include "AnimModel.h"
|
||||||
#include "simulationenvironment.h"
|
#include "simulationenvironment.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -429,6 +430,9 @@ particle_manager::find( std::string const &Template ) {
|
|||||||
// should be 'safe enough' to return lookup result directly afterwards
|
// should be 'safe enough' to return lookup result directly afterwards
|
||||||
return &( m_sourcetemplates.find( templatename )->second );
|
return &( m_sourcetemplates.find( templatename )->second );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad file: failed do locate particle source configuration file \"" + std::string( templatepath + templatename + ".txt" ) + "\"", logtype::file );
|
||||||
|
}
|
||||||
// if fetching data from the file fails too, give up
|
// if fetching data from the file fails too, give up
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "simulationtime.h"
|
#include "simulationtime.h"
|
||||||
|
#include "simulationenvironment.h"
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
@@ -57,6 +58,36 @@ state_manager::export_as_text( std::string const &Scenariofile ) const {
|
|||||||
return m_serializer.export_as_text( Scenariofile );
|
return m_serializer.export_as_text( Scenariofile );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
state_manager::init_scripting_interface() {
|
||||||
|
|
||||||
|
// create scenario data memory cells
|
||||||
|
{
|
||||||
|
auto *memorycell = new TMemCell( {
|
||||||
|
0, -1,
|
||||||
|
"__simulation.weather",
|
||||||
|
"memcell" } );
|
||||||
|
simulation::Memory.insert( memorycell );
|
||||||
|
simulation::Region->insert( memorycell );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto *memorycell = new TMemCell( {
|
||||||
|
0, -1,
|
||||||
|
"__simulation.time",
|
||||||
|
"memcell" } );
|
||||||
|
simulation::Memory.insert( memorycell );
|
||||||
|
simulation::Region->insert( memorycell );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto *memorycell = new TMemCell( {
|
||||||
|
0, -1,
|
||||||
|
"__simulation.date",
|
||||||
|
"memcell" } );
|
||||||
|
simulation::Memory.insert( memorycell );
|
||||||
|
simulation::Region->insert( memorycell );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// legacy method, calculates changes in simulation state over specified time
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
void
|
void
|
||||||
state_manager::update( double const Deltatime, int Iterationcount ) {
|
state_manager::update( double const Deltatime, int Iterationcount ) {
|
||||||
@@ -87,6 +118,54 @@ state_manager::update_clocks() {
|
|||||||
Global.fClockAngleDeg[ 5 ] = 36.0 * ( time.wHour / 10 ); // dziesiątki godzin
|
Global.fClockAngleDeg[ 5 ] = 36.0 * ( time.wHour / 10 ); // dziesiątki godzin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
state_manager::update_scripting_interface() {
|
||||||
|
|
||||||
|
auto *weather{ Memory.find( "__simulation.weather" ) };
|
||||||
|
auto *time{ Memory.find( "__simulation.time" ) };
|
||||||
|
auto *date{ Memory.find( "__simulation.date" ) };
|
||||||
|
|
||||||
|
if( simulation::is_ready ) {
|
||||||
|
// potentially adjust weather
|
||||||
|
if( weather->Value1() != m_scriptinginterface.weather->Value1() ) {
|
||||||
|
Global.Overcast = clamp<float>( weather->Value1(), 0, 2 );
|
||||||
|
simulation::Environment.compute_weather();
|
||||||
|
}
|
||||||
|
if( weather->Value2() != m_scriptinginterface.weather->Value2() ) {
|
||||||
|
Global.fFogEnd = clamp<float>( weather->Value2(), 10, 25000 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_scriptinginterface.weather = std::make_shared<TMemCell>( scene::node_data() );
|
||||||
|
m_scriptinginterface.date = std::make_shared<TMemCell>( scene::node_data() );
|
||||||
|
m_scriptinginterface.time = std::make_shared<TMemCell>( scene::node_data() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// update scripting interface
|
||||||
|
weather->UpdateValues(
|
||||||
|
Global.Weather,
|
||||||
|
Global.Overcast,
|
||||||
|
Global.fFogEnd,
|
||||||
|
basic_event::flags::text | basic_event::flags::value_1 | basic_event::flags::value_2 );
|
||||||
|
|
||||||
|
time->UpdateValues(
|
||||||
|
Global.Period,
|
||||||
|
Time.data().wHour,
|
||||||
|
Time.data().wMinute,
|
||||||
|
basic_event::flags::text | basic_event::flags::value_1 | basic_event::flags::value_2 );
|
||||||
|
|
||||||
|
date->UpdateValues(
|
||||||
|
Global.Season,
|
||||||
|
Time.year_day(),
|
||||||
|
0,
|
||||||
|
basic_event::flags::text | basic_event::flags::value_1 );
|
||||||
|
|
||||||
|
// cache cell state to detect potential script-issued changes on next cycle
|
||||||
|
*m_scriptinginterface.weather = *weather;
|
||||||
|
*m_scriptinginterface.time = *time;
|
||||||
|
*m_scriptinginterface.date = *date;
|
||||||
|
}
|
||||||
|
|
||||||
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
|
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
|
||||||
void
|
void
|
||||||
radio_message( sound_source *Message, int const Channel ) {
|
radio_message( sound_source *Message, int const Channel ) {
|
||||||
|
|||||||
@@ -18,11 +18,15 @@ class state_manager {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// methods
|
// methods
|
||||||
|
void
|
||||||
|
init_scripting_interface();
|
||||||
// legacy method, calculates changes in simulation state over specified time
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
void
|
void
|
||||||
update( double Deltatime, int Iterationcount );
|
update( double Deltatime, int Iterationcount );
|
||||||
void
|
void
|
||||||
update_clocks();
|
update_clocks();
|
||||||
|
void
|
||||||
|
update_scripting_interface();
|
||||||
// restores simulation data from specified file. returns: true on success, false otherwise
|
// restores simulation data from specified file. returns: true on success, false otherwise
|
||||||
bool
|
bool
|
||||||
deserialize( std::string const &Scenariofile );
|
deserialize( std::string const &Scenariofile );
|
||||||
@@ -33,6 +37,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
state_serializer m_serializer;
|
state_serializer m_serializer;
|
||||||
|
struct {
|
||||||
|
std::shared_ptr<TMemCell> weather, time, date;
|
||||||
|
} m_scriptinginterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
|
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
|
||||||
|
|||||||
@@ -174,6 +174,11 @@ world_environment::update() {
|
|||||||
Global.Weather == "snow:" ? 0.75f :
|
Global.Weather == "snow:" ? 0.75f :
|
||||||
1.0f );
|
1.0f );
|
||||||
|
|
||||||
|
Global.Period = (
|
||||||
|
m_sun.getAngle() > -12.0f ?
|
||||||
|
"day:" :
|
||||||
|
"night:" );
|
||||||
|
|
||||||
if( Global.Weather == "rain:" ) {
|
if( Global.Weather == "rain:" ) {
|
||||||
m_precipitationsound.play( sound_flags::exclusive | sound_flags::looping );
|
m_precipitationsound.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ state_serializer::deserialize( std::string const &Scenariofile ) {
|
|||||||
SafeDelete( Region );
|
SafeDelete( Region );
|
||||||
Region = new scene::basic_region();
|
Region = new scene::basic_region();
|
||||||
|
|
||||||
|
simulation::State.init_scripting_interface();
|
||||||
|
|
||||||
// TODO: check first for presence of serialized binary files
|
// TODO: check first for presence of serialized binary files
|
||||||
// if this fails, fall back on the legacy text format
|
// if this fails, fall back on the legacy text format
|
||||||
scene::scratch_data importscratchpad;
|
scene::scratch_data importscratchpad;
|
||||||
|
|||||||
Reference in New Issue
Block a user