17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-27 19:57:29 +01:00

feat(editor): the SRK tool shows the block of each line out of the station and places the SHP resonators: the automatic or the semi-automatic block chosen in a table of the lines, by hand or by the block signals standing along it, a double-track line taking the automatic one, a single-track one the other, kept in the record of the station; the block signals placed only on the lines of the automatic block, the warning discs only on those of the semi-automatic one. The heads checked for their resonators 200 m before an entry signal, a block signal and a warning disc and at an exit signal telling of the next one, 5 m either way, those of the old sceneries found by any event ending with _shp within 100 m; the ones missing placed as rezonator.inc with their events on the tracks the trains run into, at a joint within 5 m, else the track cut, in one step of undo. A signal stands by the track of its read event only when it lies near it, else by the nearest track, so a read event put on a track before the signal no longer shifts its routes

This commit is contained in:
maj00r
2026-10-22 18:55:21 +02:00
parent edb4f7c60d
commit fc6d1158bd
6 changed files with 1015 additions and 125 deletions

View File

@@ -278,7 +278,8 @@ std::size_t editor_mode::place_templates(std::vector<template_item> const &Items
}
else
{
std::vector<std::string> values{"none", number(local.x, 3), number(local.y, 3), number(local.z, 3), number(item.yaw, 2)};
auto const name{item.values.find("name")};
std::vector<std::string> values{name != item.values.end() ? name->second : std::string{"none"}, number(local.x, 3), number(local.y, 3), number(local.z, 3), number(item.yaw, 2)};
values.insert(values.end(), item.rest.begin(), item.rest.end());
directive = editor_includes::compose_directive(item.file, values);
}

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
#include "imgui/imgui.h"
#include <map>
#include <optional>
#include <string>
#include <unordered_set>
@@ -45,6 +46,14 @@ class srk_tool final : public editor_tool
editor_history &m_history;
editor_templates &m_templates;
editor_signals &m_signals;
// where the block of a line out of the station comes from
enum class block_reason
{
hand, // set by hand
standing, // block signals stand along it
double_track, // the automatic one on a double-track line
single // the semi-automatic one on a single-track line
};
// a station described: found again by a switch of it
struct record
{
@@ -57,6 +66,7 @@ class srk_tool final : public editor_tool
std::string km; // of the axis of the station along the line, empty while unknown
bool reversed{false}; // the km rise to the left of the schematic, the switches numbered from there
int braking{0}; // m, the braking distance of the line set by hand, 0: after its speed
std::map<std::string, bool> blocks; // of the lines by their entry signals: the automatic block on it, as set by hand
};
// the schematic: the chainage across, the offsets upwards, exaggerated
struct view
@@ -138,10 +148,33 @@ class srk_tool final : public editor_tool
bool more{false}; // its template has more than it needs
std::string fit; // the template that fits best, empty for none
std::vector<std::string> problems; // of its place
// m before it the SHP track resonator belongs, -1 for none: 200 m before an entry signal, a block signal and a warning disc,
// at an exit signal onto a line of the automatic block
double shp{-1.0};
double shp_found{-1.0}; // m before it the trains run into the event of the SHP resonator standing, -1 for none
bool shp_short{false}; // the tracks before it end short of the place of its resonator
};
std::vector<head_check> m_heads;
bool m_heads_known{false}; // the templates found
int m_head_hover{-1}; // of the heads, the row under the mouse
// a line out of the open station, from an entry signal of it
struct line_row
{
std::string entry; // the entry signal, shown
glm::dvec3 position{0.0}; // of the entry signal
glm::dvec2 travel{0.0, 1.0}; // the trains it faces run, in the plan
int number{0}; // of the track of a double-track line, 0 on a single-track one
bool inbound{true}; // its trains run towards the station
int partner{-1}; // the other track of a double-track line, of the lines
double length{0.0}; // to the entry signal of the next station, or to the end of the tracks
std::string next; // the entry signal of the next station facing out along it, shown; empty for none
bool station{false}; // ends at the next station rather than at the end of the tracks
std::size_t blocks{0}; // the block signals standing along it
bool automatic{false}; // of the automatic block
block_reason why{block_reason::single}; // the block it has, so
};
std::vector<line_row> m_lines;
std::string m_lines_problem; // why the station has no lines listed
std::string m_status;
void load();
@@ -186,6 +219,19 @@ class srk_tool final : public editor_tool
// the signals of the lines out of the station: on a double-track line the block signals to the next station and the block
// sections between them, on a single-track one a warning disc before the entry signal; one step of the history
void set_lines();
// the lines out of the open station from its entry signals standing, Entries: the signals of the plan they begin at, Owners:
// the standing ones; false with the reason while it has none
bool lines_of_open(std::vector<standing_signal> const &Standing, std::vector<station::line> &Lines, std::vector<station::signal> &Entries, std::vector<std::size_t> &Owners, std::string &Problem) const;
// the line has the automatic block: as set by hand for its entry signal, else where block signals stand along it, else on a
// double-track line
bool automatic_block(station::line const &Line, std::string const &Entry, std::vector<standing_signal> const &Standing, block_reason &Why, std::size_t &Blocks) const;
// the lines out of the open station, for the panel
void survey_lines(std::vector<standing_signal> const &Standing);
void render_lines();
// the SHP track resonators placed where the signals checked need them and have none: 200 m before an entry signal, a block
// signal and a warning disc, at an exit signal onto a line of the automatic block, the track cut where none of its joints lies
// within 5 m, its event put on the track the trains run into there; one step of the history
void set_shp();
// the names of the switches and the circuits of the open station begin with it, empty while it has no code
std::string stem_of_open() const;
// the km at the chainage of the open station: of the kilometrage of its line, else of its record, else of its switches; false

View File

@@ -2229,4 +2229,65 @@ std::vector<std::vector<route>> routes(std::vector<post> const &Posts, std::vect
return all;
}
std::vector<approach_point> approach(TTrack &Track, glm::dvec3 const &Point, int const Facing, double const Distance)
{
std::vector<approach_point> result;
if (false == rail(Track))
return result;
auto *track{&Track};
int path{0};
long at{0};
std::vector<glm::dvec3> points;
auto nearest{std::numeric_limits<double>::max()};
for (int candidate = 0; candidate < static_cast<int>(Track.m_paths.size()); ++candidate)
{
double length{0.0};
auto dense{dense_points(Track, candidate, length)};
for (std::size_t k = 0; k < dense.size(); ++k)
if (auto const gap{plan_distance(dense[k], Point)}; gap < nearest - 1e-6)
{
nearest = gap;
path = candidate;
at = static_cast<long>(k);
}
if (path == candidate)
points = std::move(dense);
}
auto facing{Facing > 0 ? 1 : -1};
auto last{points[at]};
double distance{0.0};
std::unordered_set<TTrack const *> seen{track};
while (true)
{
auto const count{static_cast<long>(points.size())};
auto const step{facing > 0 ? -1L : 1L};
for (auto k{at}; k >= 0 && k < count; k += step)
{
distance += plan_distance(last, points[k]);
last = points[k];
auto const ahead{points[std::clamp(k + 1, 0L, count - 1)] - points[std::clamp(k - 1, 0L, count - 1)]};
glm::dvec3 way{ahead.x * facing, 0.0, ahead.z * facing};
way = glm::length(way) > 1e-9 ? glm::normalize(way) : glm::dvec3{0.0, 0.0, 1.0};
result.push_back({track, path, facing, points[k], way, distance});
if (distance >= Distance)
return result;
}
auto const atend{facing < 0};
auto const end{end_of(*track, path, atend)};
auto *before{neighbour(*track, path, atend)};
int entered{0};
bool from_end{false};
if (before == nullptr || false == rail(*before) || false == seen.insert(before).second || false == end_at(*before, end, entered, from_end))
return result;
if (before->eType == tt_Switch && false == from_end)
entered = straighter(*before);
track = before;
path = entered;
double length{0.0};
points = dense_points(*track, path, length);
facing = from_end ? 1 : -1;
at = from_end ? static_cast<long>(points.size()) - 2 : 1;
}
}
} // namespace station

View File

@@ -249,4 +249,18 @@ double path_speed(TTrack const &Track, int const Path);
// the routes of the trains from each of the posts given on through the switches, none longer than the limit
std::vector<std::vector<route>> routes(std::vector<post> const &Posts, std::vector<std::size_t> const &From, double const Limit);
// a point of the way of the trains up to a signal
struct approach_point
{
TTrack *track{nullptr};
int path{0};
int facing{1}; // the trains run 1: towards the end of the path, -1: towards its start
glm::dvec3 point{0.0};
glm::dvec3 way{0.0, 0.0, 1.0}; // the trains run, in the plan
double distance{0.0}; // m, before the signal
};
// the way of the trains running past the point of the track the way given, back along the tracks they come by up to the distance
// before it or the end of the tracks, a metre or so apart: into a switch from its start along its straighter path
std::vector<approach_point> approach(TTrack &Track, glm::dvec3 const &Point, int const Facing, double const Distance);
} // namespace station

View File

@@ -10494,8 +10494,8 @@ msgstr "Szlaki"
msgid "Set the line signals"
msgstr "Ustaw sygnalizatory szlakowe"
msgid "Places the signals of the lines out of the station, from its entry signals on. A double-track line gets the automatic block: block signals evenly to the entry signals of the next station, a section no shorter than the braking distance, numbered after the hectometre ahead of them, odd on track 1, even on track 2, and the block sections from 15 m beyond them named as on the lines of PKP PLK, 2411-2571@LK2.1. A single-track line gets a warning disc ToA the braking distance before the entry signal. The braking distance after the speed of the line, as Ie-4 gives it: 400 m up to 60 km/h, 700 m up to 100, 1000 m up to 140, 1300 m above. Needs the line and the km of the station. Run it at the next station too, it keeps what stands. One step of undo"
msgstr "Stawia sygnalizatory szlaków wychodzących ze stacji, od jej semaforów wjazdowych. Szlak dwutorowy dostaje samoczynną blokadę liniową: semafory SBL rozstawione równo do semaforów wjazdowych następnej stacji, odstęp nie krótszy od drogi hamowania, numerowane według najbliższego hektometra przed nimi, nieparzyste na torze 1, parzyste na torze 2, a odstępy od 15 m za nimi nazwane jak na liniach PKP PLK, 2411-2571@LK2.1. Szlak jednotorowy dostaje tarczę ostrzegawczą ToA w odległości drogi hamowania przed semaforem wjazdowym. Droga hamowania według prędkości szlaku, jak w Ie-4: 400 m do 60 km/h, 700 m do 100, 1000 m do 140, 1300 m powyżej. Potrzebna linia i kilometr stacji. Uruchom to też na następnej stacji, zostawia to, co już stoi. Jeden krok cofania"
msgid "Places the signals of the lines out of the station, from its entry signals on, by the block chosen for each line above. The automatic block: block signals evenly to the entry signals of the next station, a section no shorter than the braking distance, numbered after the hectometre ahead of them, odd on track 1, even on track 2, and the block sections from 15 m beyond them named as on the lines of PKP PLK, 2411-2571@LK2.1. The semi-automatic block: a warning disc ToA the braking distance before the entry signal. The braking distance after the speed of the line, as Ie-4 gives it: 400 m up to 60 km/h, 700 m up to 100, 1000 m up to 140, 1300 m above. Needs the line and the km of the station. Run it at the next station too, it keeps what stands. One step of undo"
msgstr "Stawia sygnalizatory szlaków wychodzących ze stacji, od jej semaforów wjazdowych, według blokady wybranej wyżej dla każdego szlaku. Blokada samoczynna: semafory SBL rozstawione równo do semaforów wjazdowych następnej stacji, odstęp nie krótszy od drogi hamowania, numerowane według najbliższego hektometra przed nimi, nieparzyste na torze 1, parzyste na torze 2, a odstępy od 15 m za nimi nazwane jak na liniach PKP PLK, 2411-2571@LK2.1. Blokada półsamoczynna: tarcza ostrzegawcza ToA w odległości drogi hamowania przed semaforem wjazdowym. Droga hamowania według prędkości szlaku, jak w Ie-4: 400 m do 60 km/h, 700 m do 100, 1000 m do 140, 1300 m powyżej. Potrzebna linia i kilometr stacji. Uruchom to też na następnej stacji, zostawia to, co już stoi. Jeden krok cofania"
msgid "Km"
msgstr "Kilometr"
@@ -11053,11 +11053,11 @@ msgstr "Światła semaforów już pasują"
msgid "The signals couldn't be changed: %s"
msgstr "Nie udało się zmienić semaforów: %s"
msgid "%zu signal of the lines fits"
msgid_plural "%zu signals of the lines fit"
msgstr[0] "%zu semafor linii pasuje"
msgstr[1] "%zu semafory linii pasują"
msgstr[2] "%zu semaforów linii pasuje"
msgid "%zu signal of the lines fits, its SHP too"
msgid_plural "%zu signals of the lines fit, their SHP too"
msgstr[0] "%zu semafor szlaku pasuje, jego SHP też"
msgstr[1] "%zu semafory szlaku pasują, ich SHP też"
msgstr[2] "%zu semaforów szlaku pasuje, ich SHP też"
msgid "%zu signal got the lights it needs, Ctrl+Z takes it back"
msgid_plural "%zu signals got the lights they need, Ctrl+Z takes it back"
@@ -11065,7 +11065,6 @@ msgstr[0] "%zu semafor dostał potrzebne światła, Ctrl+Z cofa"
msgstr[1] "%zu semafory dostały potrzebne światła, Ctrl+Z cofa"
msgstr[2] "%zu semaforów dostało potrzebne światła, Ctrl+Z cofa"
msgid "Template: %s"
msgstr "Szablon: %s"
@@ -11077,3 +11076,174 @@ msgstr "Semafor %s dostał szablon %s, Ctrl+Z cofa"
msgid "Signal %s can't take the template %s"
msgstr "Semafor %s nie może dostać szablonu %s"
msgid "SHP"
msgstr "SHP"
msgid "Place the SHP resonators"
msgstr "Postaw rezonatory SHP"
msgid "Places the SHP track resonators the signals checked lack, rezonator.inc, as PKP PLK places them: 200 m before an entry signal, a block signal and a warning disc, at an exit signal telling of the next one, as one onto a line of the automatic block, 5 m either way. Its event goes on the track the trains run into there, at a joint of the tracks within 5 m, else the track is cut. A resonator standing is one whose event ends with _shp, put on a track the trains run into within 100 m of its place, so the ones of the old sceneries count too. One step of undo"
msgstr "Stawia rezonatory SHP (rezonator.inc) tam, gdzie sprawdzonym semaforom ich brakuje, tak jak PKP PLK: 200 m przed semaforem wjazdowym, semaforem SBL i tarczą ostrzegawczą, a przy semaforze wyjazdowym, który zapowiada następny semafor, np. przy wyjeździe na szlak z SBL; ±5 m. Event rezonatora trafia na tor, na który pociąg tam wjeżdża: na styku torów, jeśli jakiś jest w promieniu 5 m, inaczej tor zostaje przecięty. Za stojący rezonator uznaje się każdy event kończący się na _shp na torze w promieniu 100 m od miejsca rezonatora, więc liczą się też te ze starych scenerii. Jeden krok cofania"
msgid "%zu of %zu signal has its SHP resonator"
msgid_plural "%zu of %zu signals have their SHP resonators"
msgstr[0] "%zu z %zu semafora ma rezonator SHP"
msgstr[1] "%zu z %zu semaforów ma rezonatory SHP"
msgstr[2] "%zu z %zu semaforów ma rezonatory SHP"
msgid "%zu farther than 5 m from its place"
msgid_plural "%zu farther than 5 m from their places"
msgstr[0] "%zu dalej niż 5 m od swojego miejsca"
msgstr[1] "%zu dalej niż 5 m od swoich miejsc"
msgstr[2] "%zu dalej niż 5 m od swoich miejsc"
msgid "set by hand"
msgstr "ustawiona ręcznie"
msgid "block signals stand along it"
msgstr "stoją na nim semafory SBL"
msgid "a double-track line"
msgstr "linia dwutorowa"
msgid "a single-track line"
msgstr "linia jednotorowa"
msgid "automatic (SBL)"
msgstr "samoczynna (SBL)"
msgid "semi-automatic"
msgstr "półsamoczynna"
msgid "To"
msgstr "Dokąd"
msgid "Block"
msgstr "Blokada"
msgid "single track"
msgstr "jednotorowy"
msgid "track %d"
msgstr "tor %d"
msgid "The line out beyond the entry signal %s"
msgstr "Szlak za semaforem wjazdowym %s"
msgid "Track %d of a double-track line"
msgstr "Tor %d linii dwutorowej"
msgid "its trains run in to the station"
msgstr "pociągi jadą nim do stacji"
msgid "its trains run out of the station"
msgstr "pociągi jadą nim ze stacji"
msgid "A single-track line"
msgstr "Linia jednotorowa"
msgid "%zu block signal stands along it"
msgid_plural "%zu block signals stand along it"
msgstr[0] "Stoi na nim %zu semafor SBL"
msgstr[1] "Stoją na nim %zu semafory SBL"
msgstr[2] "Stoi na nim %zu semaforów SBL"
msgid "Block: %s, %s"
msgstr "Blokada: %s, %s"
msgid "LMB: fly to the entry signal"
msgstr "LPM: leć do semafora wjazdowego"
msgid "station"
msgstr "stacja"
msgid "track end"
msgstr "koniec toru"
msgid "To the entry signal %s of the next station"
msgstr "Do semafora wjazdowego %s następnej stacji"
msgid "To the next station, its entry signal not standing yet"
msgstr "Do następnej stacji, jej semafor wjazdowy jeszcze nie stoi"
msgid "To the end of the tracks"
msgstr "Do końca torów"
msgid "%s, auto"
msgstr "%s, auto"
msgid "Auto: %s, %s"
msgstr "Auto: %s, %s"
msgid "Automatic block (SBL)"
msgstr "Blokada samoczynna (SBL)"
msgid "Placed on a double-track line only: on a single track the block signals would face both ways, the editor leaves those standing as they are"
msgstr "Edytor stawia ją tylko na linii dwutorowej: na jednym torze semafory SBL musiałyby stać w obu kierunkach, takie, które już stoją, zostawia bez zmian"
msgid "Semi-automatic block"
msgstr "Blokada półsamoczynna"
msgid "The block of the line, both tracks of a double-track one alike. Automatic (SBL): block signals with block sections, no warning disc. Semi-automatic: a warning disc ToA the braking distance before the entry signal. By itself: the automatic one where block signals stand along the line or it's double-track, else the semi-automatic one"
msgstr "Blokada liniowa szlaku, na dwutorowym taka sama na obu torach. Samoczynna (SBL): semafory SBL z odstępami blokowymi, bez tarczy ostrzegawczej. Półsamoczynna: tarcza ostrzegawcza ToA w odległości drogi hamowania przed semaforem wjazdowym. Auto: samoczynna, gdy na szlaku stoją semafory SBL albo linia jest dwutorowa, inaczej półsamoczynna"
msgid "its SHP resonator belongs %.0f m before it"
msgstr "rezonator SHP powinien stać %.0f m przed nim"
msgid "its SHP resonator belongs at it, it tells of the next signal"
msgstr "rezonator SHP powinien stać przy nim, bo zapowiada następny semafor"
msgid "none stands"
msgstr "nie ma go"
msgid "its event %.0f m before it"
msgstr "jego event jest %.0f m przed nim"
msgid "%s isn't in the scenery folder: the SHP resonators can't be placed"
msgstr "Brak %s w folderze scenerii: nie da się postawić rezonatorów SHP"
msgid "%s stands by no track"
msgstr "%s nie stoi przy żadnym torze"
msgid "%s: the tracks before it end short of %.0f m"
msgstr "%s: tory przed nim kończą się przed %.0f m"
msgid "%s: no plain track within %.0f m of the place of its SHP resonator"
msgstr "%s: w miejscu rezonatora SHP (±%.0f m) nie ma zwykłego toru, same rozjazdy"
msgid "%s: vehicles stand on %s"
msgstr "%s: na %s stoją pojazdy"
msgid "The signals have their SHP resonators already"
msgstr "Semafory mają już rezonatory SHP"
msgid "%zu SHP resonator placed"
msgid_plural "%zu SHP resonators placed"
msgstr[0] "Postawiono %zu rezonator SHP"
msgstr[1] "Postawiono %zu rezonatory SHP"
msgstr[2] "Postawiono %zu rezonatorów SHP"
msgid "%zu track cut"
msgid_plural "%zu tracks cut"
msgstr[0] "przecięto %zu tor"
msgstr[1] "przecięto %zu tory"
msgstr[2] "przecięto %zu torów"
msgid "Ctrl+Z takes it back, the resonators work after the scenery is saved and opened again"
msgstr "Ctrl+Z cofa, rezonatory działają po zapisaniu i ponownym otwarciu scenerii"
msgid "The SHP resonators couldn't be placed: %s"
msgstr "Nie udało się postawić rezonatorów SHP: %s"
msgid "at it"
msgstr "przy nim"
msgid "the tracks before it end short of it"
msgstr "tory przed nim kończą się wcześniej"
msgid "%zu with the tracks ending short of the place of its resonator"
msgid_plural "%zu with the tracks ending short of the places of their resonators"
msgstr[0] "%zu ma tory kończące się przed miejscem rezonatora"
msgstr[1] "%zu mają tory kończące się przed miejscem rezonatora"
msgstr[2] "%zu ma tory kończące się przed miejscem rezonatora"