diff --git a/simulation/simulationstateserializer.cpp b/simulation/simulationstateserializer.cpp index 1ff771d1d..78955c828 100644 --- a/simulation/simulationstateserializer.cpp +++ b/simulation/simulationstateserializer.cpp @@ -543,6 +543,12 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch else if( nodedata.type == "track" ) { auto *path { deserialize_path( Input, Scratchpad, nodedata ) }; + if( path->eType == tt_Unknown ) { + // with no path made it can't be joined nor drawn, and nothing could run on it + ErrorLog( "Bad scenario: track \"" + path->name() + "\" of an unknown type defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ") left out" ); + delete path; + return; + } // duplicates of named tracks are currently experimentally allowed if( false == simulation::Paths.insert( path ) ) { ErrorLog( "Bad scenario: duplicate track name \"" + path->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); diff --git a/world/Track.cpp b/world/Track.cpp index f1a29798c..14998ce7c 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -427,11 +427,15 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) } else if (str == "tributary") { - eType = tt_Tributary; + // dopływ: no path of it was ever made, the simulator falling over it as it loaded. a river of its first path now, the + // second one kept and written back + ErrorLog("Bad track: tributary \"" + m_name + "\" in file \"" + parser->Name() + "\" (line " + std::to_string(parser->Line()) + ") is drawn and run on as a river of its first path"); + eType = tt_Normal; iCategoryFlag = 4; + m_tributary = true; } else - eType = tt_Unknown; + eType = tt_Unknown; // left out by the loader if (Global.iWriteLogEnabled & 4) WriteLog(str); parser->getTokens(4); @@ -517,6 +521,11 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) break; } } + if( m_tributary ) { + // the second path of a tributary, kept to be written back + m_paths.emplace_back(); + m_paths.back().deserialize( *parser, pOrigin ); + } init_segments( true ); @@ -681,6 +690,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) m_name = m_name.substr(0, i - 1); // usunięcie z nazwy } + if( CurrentSegment() == nullptr ) { + // of an unknown type, no path of it is made + return; + } update_location(); // sleeper transforms are baked later in create_geometry(), once the owning cell has // assigned this track its m_origin (otherwise the local-space matrices would be relative @@ -2314,6 +2327,7 @@ TTrack::export_as_text_( std::ostream &Output ) const { // type Output << ( eType == tt_Normal ? ( + m_tributary ? "tributary" : iCategoryFlag == 1 ? "normal" : iCategoryFlag == 2 ? "road" : iCategoryFlag == 4 ? "river" : diff --git a/world/Track.h b/world/Track.h index 72a6b7ff4..5952da6a7 100644 --- a/world/Track.h +++ b/world/Track.h @@ -187,6 +187,7 @@ public: std::vector m_paths; // source data for owned paths bool m_editorremoved { false }; + bool m_tributary { false }; // loaded as a tributary: a river of its first path, the second one kept to be written back scene::basic_node *m_road { nullptr }; // road or road junction which generated this path. such path is one-way, and isn't saved nor edited on its own std::array m_routeweights { 0.f, 0.f, 0.f }; // odds of each route through a crossroads being picked by a driver, by the number of the route. all zero: even odds int iterate_stamp = 0;