mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-20 11:29:18 +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 };
|
||||
std::string Season{}; // season of the year, based on simulation date
|
||||
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 bnewAirCouplers{ true };
|
||||
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 MainsInitTimeCountdown{ 0.0 }; // current state of main circuit initialization, remaining time (in seconds) until it's ready
|
||||
bool LineBreakerClosesAtNoPowerPosOnly{ false };
|
||||
bool HasPressureSwitch{ true };
|
||||
int MainCtrlPos = 0; /*polozenie glownego nastawnika*/
|
||||
int ScndCtrlPos = 0; /*polozenie dodatkowego nastawnika*/
|
||||
int LightsPos = 0; /*polozenie przelacznika wielopozycyjnego swiatel*/
|
||||
|
||||
@@ -6222,9 +6222,8 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
// main bez samoczynnego rozruchu
|
||||
if( ( MainCtrlActualPos < ( sizeof( RList ) / sizeof( TScheme ) - 1 ) ) // crude guard against running out of current fixed table
|
||||
&& ( ( RList[ MainCtrlActualPos ].Relay < MainCtrlPos )
|
||||
|| ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos )
|
||||
|| ( ( TrainType == dt_ET22 )
|
||||
&& ( DelayCtrlFlag ) ) ) ) {
|
||||
|| ( ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos ) && ( MainCtrlActualPos < RlistSize ) )
|
||||
|| ( ( TrainType == dt_ET22 ) && ( DelayCtrlFlag ) ) ) ) {
|
||||
|
||||
if( ( RList[MainCtrlPos].R == 0 )
|
||||
&& ( MainCtrlPos > 0 )
|
||||
@@ -6359,7 +6358,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
&& ( ( MainCtrlActualPos > 0 )
|
||||
|| ( ScndCtrlActualPos > 0 ) ) ) {
|
||||
|
||||
if( CoupledCtrl || HasCamshaft ) {
|
||||
if( CoupledCtrl ) {
|
||||
|
||||
if( TrainType == dt_EZT ) {
|
||||
// EN57 wal jednokierunkowy calosciowy
|
||||
@@ -6393,8 +6392,7 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
else {
|
||||
// wal kulakowy dwukierunkowy
|
||||
if( LastRelayTime > CtrlDownDelay ) {
|
||||
if( ( CoupledCtrl )
|
||||
&& ( ScndCtrlActualPos > 0 ) ) {
|
||||
if( ScndCtrlActualPos > 0 ) {
|
||||
--ScndCtrlActualPos;
|
||||
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 {
|
||||
MainCtrlActualPos = 0;
|
||||
ScndCtrlActualPos = 0;
|
||||
@@ -6424,6 +6432,7 @@ bool TMoverParameters::MotorConnectorsCheck() {
|
||||
// hunter-111211: wylacznik cisnieniowy
|
||||
auto const pressureswitch {
|
||||
( TrainType != dt_EZT )
|
||||
&& ( HasPressureSwitch )
|
||||
&& ( ( BrakePress > 2.0 )
|
||||
|| ( PipePress < 3.6 ) ) };
|
||||
|
||||
@@ -10090,6 +10099,8 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
||||
// traction motors
|
||||
extract_value( MotorBlowers[ end::front ].speed, "MotorBlowersSpeed", Input, "" );
|
||||
MotorBlowers[ end::rear ] = MotorBlowers[ end::front ];
|
||||
// pressure switch
|
||||
extract_value( HasPressureSwitch, "PressureSwitch", 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::pantographselectnext, &TTrain::OnCommand_pantographselectnext },
|
||||
{ user_command::pantographselectprevious, &TTrain::OnCommand_pantographselectprevious },
|
||||
{ user_command::pantographtoggleselected, &TTrain::OnCommand_pantographtoggleselected },
|
||||
{ user_command::pantographraiseselected, &TTrain::OnCommand_pantographraiseselected },
|
||||
{ user_command::pantographlowerselected, &TTrain::OnCommand_pantographlowerselected },
|
||||
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
|
||||
@@ -2224,6 +2225,37 @@ void TTrain::OnCommand_pantographselectprevious( TTrain *Train, command_data con
|
||||
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 ) {
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
@@ -2231,18 +2263,15 @@ void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data cons
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// raise selected
|
||||
Train->mvControlled->OperatePantographsValve(
|
||||
Train->ggPantSelectedButton.type() == TGaugeType::toggle ?
|
||||
operation_t::enable :
|
||||
operation_t::enable_on );
|
||||
Train->ggPantSelectedButton.type() != TGaugeType::toggle ?
|
||||
operation_t::enable_on :
|
||||
operation_t::enable );
|
||||
// visual feedback
|
||||
Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) {
|
||||
Train->mvControlled->OperatePantographsValve( operation_t::enable_off );
|
||||
// visual feedback
|
||||
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
|
||||
OnCommand_pantographtoggleselected( Train, Command );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2253,18 +2282,18 @@ void TTrain::OnCommand_pantographlowerselected( TTrain *Train, command_data cons
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// lower selected
|
||||
Train->mvControlled->OperatePantographsValve(
|
||||
Train->ggPantSelectedDownButton.type() == TGaugeType::toggle ?
|
||||
operation_t::disable :
|
||||
operation_t::disable_on );
|
||||
Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ?
|
||||
operation_t::disable_on :
|
||||
operation_t::disable );
|
||||
// visual feedback
|
||||
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 ) {
|
||||
if( Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ) {
|
||||
Train->mvControlled->OperatePantographsValve( operation_t::disable_off );
|
||||
// visual feedback
|
||||
Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
|
||||
OnCommand_pantographtoggleselected( Train, Command );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5682,7 +5711,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
||||
// nie blokujemy AI
|
||||
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...
|
||||
// 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::mastercontrollerdecrease ) ) ) {
|
||||
*/
|
||||
if( false == m_mastercontrollerinuse ) {
|
||||
if( false == ( m_mastercontrollerinuse || Global.ctrlState ) ) {
|
||||
m_mastercontrollerreturndelay -= Deltatime;
|
||||
if( m_mastercontrollerreturndelay < 0.f ) {
|
||||
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_pantographselectnext( 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_pantographlowerselected( 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 );
|
||||
}
|
||||
|
||||
void
|
||||
eu07_application::set_tooltip( std::string const &Tooltip ) {
|
||||
|
||||
if( m_modestack.empty() ) { return; }
|
||||
|
||||
m_modes[ m_modestack.top() ]->set_tooltip( Tooltip );
|
||||
}
|
||||
|
||||
void
|
||||
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 );
|
||||
}
|
||||
/*
|
||||
// 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
|
||||
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 );
|
||||
void
|
||||
set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f );
|
||||
void
|
||||
set_tooltip( std::string const &Tooltip );
|
||||
void
|
||||
set_cursor( int const Mode );
|
||||
void
|
||||
@@ -62,6 +64,11 @@ public:
|
||||
get_cursor_pos( double &Horizontal, double &Vertical ) const;
|
||||
int
|
||||
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
|
||||
void
|
||||
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 },
|
||||
{ "pantographselectnext", command_target::vehicle },
|
||||
{ "pantographselectprevious", command_target::vehicle },
|
||||
{ "pantographtoggleselected", command_target::vehicle },
|
||||
{ "pantographraiseselected", command_target::vehicle },
|
||||
{ "pantographlowerselected", command_target::vehicle },
|
||||
{ "heatingtoggle", command_target::vehicle },
|
||||
|
||||
@@ -173,6 +173,7 @@ enum class user_command {
|
||||
pantographlowerall,
|
||||
pantographselectnext,
|
||||
pantographselectprevious,
|
||||
pantographtoggleselected,
|
||||
pantographraiseselected,
|
||||
pantographlowerselected,
|
||||
heatingtoggle,
|
||||
|
||||
@@ -182,8 +182,9 @@ driverkeyboard_input::default_bindings() {
|
||||
{ user_command::pantographlowerall, GLFW_KEY_P | keymodifier::control },
|
||||
{ user_command::pantographselectnext, GLFW_KEY_P | keymodifier::shift },
|
||||
{ user_command::pantographselectprevious, GLFW_KEY_O | keymodifier::shift },
|
||||
{ user_command::pantographraiseselected, GLFW_KEY_O | keymodifier::shift | keymodifier::control },
|
||||
{ user_command::pantographlowerselected, GLFW_KEY_O | keymodifier::control },
|
||||
{ user_command::pantographtoggleselected, GLFW_KEY_O | keymodifier::shift | keymodifier::control },
|
||||
// pantographraiseselected,
|
||||
// pantographlowerselected,
|
||||
{ user_command::heatingtoggle, GLFW_KEY_H },
|
||||
// heatingenable,
|
||||
// heatingdisable,
|
||||
|
||||
@@ -151,6 +151,7 @@ driver_mode::update() {
|
||||
simulation::Time.update( deltatime );
|
||||
}
|
||||
simulation::State.update_clocks();
|
||||
simulation::State.update_scripting_interface();
|
||||
simulation::Environment.update();
|
||||
|
||||
// fixed step, simulation time based updates
|
||||
|
||||
@@ -793,7 +793,7 @@ drivermouse_input::default_bindings() {
|
||||
user_command::pantographlowerall,
|
||||
user_command::none } },
|
||||
{ "pantselected_sw:", {
|
||||
user_command::pantographraiseselected,
|
||||
user_command::pantographtoggleselected,
|
||||
user_command::none } }, // TBD: bind lowerselected in case of toggle switch
|
||||
{ "pantselectedoff_sw:", {
|
||||
user_command::pantographlowerselected,
|
||||
|
||||
@@ -542,31 +542,7 @@ debug_panel::render() {
|
||||
render_section( "Vehicle Engine", m_enginelines );
|
||||
render_section( "Vehicle AI", m_ailines );
|
||||
render_section( "Vehicle Scan Table", m_scantablelines );
|
||||
if( true == render_section( "Scenario", m_scenariolines ) ) {
|
||||
// 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
render_section_scenario();
|
||||
if( true == render_section( "Scenario Event Queue", m_eventqueuelines ) ) {
|
||||
// event queue filter
|
||||
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
||||
@@ -584,6 +560,63 @@ debug_panel::render() {
|
||||
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
|
||||
debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ private:
|
||||
std::string update_vehicle_brake() const;
|
||||
// renders provided lines, under specified collapsing header
|
||||
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||
bool render_section_scenario();
|
||||
// members
|
||||
std::array<char, 1024> m_buffer;
|
||||
input_data m_input;
|
||||
|
||||
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Globals.h"
|
||||
#include "AnimModel.h"
|
||||
#include "simulationenvironment.h"
|
||||
#include "Logs.h"
|
||||
|
||||
|
||||
void
|
||||
@@ -429,6 +430,9 @@ particle_manager::find( std::string const &Template ) {
|
||||
// should be 'safe enough' to return lookup result directly afterwards
|
||||
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
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "simulation.h"
|
||||
#include "simulationtime.h"
|
||||
#include "simulationenvironment.h"
|
||||
|
||||
#include "Globals.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 );
|
||||
}
|
||||
|
||||
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
|
||||
void
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
void
|
||||
radio_message( sound_source *Message, int const Channel ) {
|
||||
|
||||
@@ -18,11 +18,15 @@ class state_manager {
|
||||
|
||||
public:
|
||||
// methods
|
||||
void
|
||||
init_scripting_interface();
|
||||
// legacy method, calculates changes in simulation state over specified time
|
||||
void
|
||||
update( double Deltatime, int Iterationcount );
|
||||
void
|
||||
update_clocks();
|
||||
void
|
||||
update_scripting_interface();
|
||||
// restores simulation data from specified file. returns: true on success, false otherwise
|
||||
bool
|
||||
deserialize( std::string const &Scenariofile );
|
||||
@@ -33,6 +37,9 @@ public:
|
||||
private:
|
||||
// members
|
||||
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
|
||||
|
||||
@@ -174,6 +174,11 @@ world_environment::update() {
|
||||
Global.Weather == "snow:" ? 0.75f :
|
||||
1.0f );
|
||||
|
||||
Global.Period = (
|
||||
m_sun.getAngle() > -12.0f ?
|
||||
"day:" :
|
||||
"night:" );
|
||||
|
||||
if( Global.Weather == "rain:" ) {
|
||||
m_precipitationsound.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ state_serializer::deserialize( std::string const &Scenariofile ) {
|
||||
SafeDelete( Region );
|
||||
Region = new scene::basic_region();
|
||||
|
||||
simulation::State.init_scripting_interface();
|
||||
|
||||
// TODO: check first for presence of serialized binary files
|
||||
// if this fails, fall back on the legacy text format
|
||||
scene::scratch_data importscratchpad;
|
||||
|
||||
Reference in New Issue
Block a user