mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-26 22:54:54 +01:00
refactor(editor): the SRK tool judges the SHP resonator of a signal in one place, missing, beyond the tracks, off its place or placed, and picks the place of a resonator, a joint or a cut, apart from placing it; the nearest point of a track to a signal found coarsely and narrowed down rather than by up to 4000 points. A resonator whose event would land away from its place, the track not cut there, is left out with a note, and the status after a failed placing tells Ctrl+Z takes the cuts back; the lines out of a station emptied while the signal templates are looked for, the layout of the station read only once it's known open
This commit is contained in:
@@ -80,6 +80,8 @@ double constexpr kUnequal{20.0}; // m, the useful lengths of the two ways differ
|
||||
ImU32 constexpr kUnfit{IM_COL32(255, 190, 40, 255)};
|
||||
double constexpr kFastest{250.0}; // km/h, a track set faster is taken for one without a limit
|
||||
ImVec4 constexpr kWrong{1.0f, 0.42f, 0.36f, 1.0f};
|
||||
ImVec4 constexpr kDoubtful{1.0f, 0.75f, 0.3f, 1.0f};
|
||||
ImVec4 constexpr kRight{0.45f, 0.85f, 0.45f, 1.0f};
|
||||
|
||||
bool is_switch(TTrack const &Track)
|
||||
{
|
||||
@@ -425,18 +427,36 @@ double route_reach(double const Braking)
|
||||
return std::max(3000.0, 3.0 * Braking);
|
||||
}
|
||||
|
||||
// how far the point lies from the path in the plan, Parameter: of the nearest point of it, a metre or so apart
|
||||
// how far the point lies from the path in the plan, Parameter: of the nearest point of it, found among points 8 m or so apart and
|
||||
// narrowed down between the two by them
|
||||
double nearest_of(TTrack const &Track, int const Path, glm::dvec3 const &Point, double &Parameter)
|
||||
{
|
||||
geometry::bezier const curve{Track.m_paths[Path]};
|
||||
auto const count{std::clamp(static_cast<int>(curve.plan_length(16)), 64, 4000)};
|
||||
auto const gap = [&](double const At) { return geometry::plan_distance(curve.point(At), Point); };
|
||||
auto const count{std::clamp(static_cast<int>(curve.plan_length(16) / 8.0), 16, 512)};
|
||||
auto best{std::numeric_limits<double>::max()};
|
||||
for (int k = 0; k <= count; ++k)
|
||||
if (auto const distance{geometry::plan_distance(curve.point(static_cast<double>(k) / count), Point)}; distance < best)
|
||||
if (auto const distance{gap(static_cast<double>(k) / count)}; distance < best)
|
||||
{
|
||||
best = distance;
|
||||
Parameter = static_cast<double>(k) / count;
|
||||
}
|
||||
auto low{std::max(0.0, Parameter - 1.0 / count)};
|
||||
auto high{std::min(1.0, Parameter + 1.0 / count)};
|
||||
for (int step = 0; step < 40; ++step)
|
||||
{
|
||||
auto const first{low + (high - low) / 3.0};
|
||||
auto const second{high - (high - low) / 3.0};
|
||||
if (gap(first) < gap(second))
|
||||
high = second;
|
||||
else
|
||||
low = first;
|
||||
}
|
||||
if (auto const narrowed{(low + high) * 0.5}; gap(narrowed) < best)
|
||||
{
|
||||
best = gap(narrowed);
|
||||
Parameter = narrowed;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
@@ -573,8 +593,50 @@ double shp_before(std::vector<station::approach_point> const &Way, glm::dvec3 co
|
||||
return best;
|
||||
}
|
||||
|
||||
// m from the point to the nearer end of the track
|
||||
double end_gap(TTrack const &Track, glm::dvec3 const &Point)
|
||||
{
|
||||
auto const &ends{Track.m_paths.front().points};
|
||||
return std::min(glm::distance(Point, ends[segment_data::point::start]), glm::distance(Point, ends[segment_data::point::end]));
|
||||
}
|
||||
|
||||
// of the way of the trains, the point the SHP resonator wanted m before the signal goes at, within kShpTolerance: a joint of the
|
||||
// tracks, Joint, its event put on the plain track the trains run into there, else a point of a plain track away from its ends, the
|
||||
// track cut at it; -1 for none
|
||||
int resonator_at(std::vector<station::approach_point> const &Way, double const Wanted, bool &Joint)
|
||||
{
|
||||
auto best{-1};
|
||||
auto miss{kShpTolerance + 1e-6};
|
||||
Joint = false;
|
||||
for (std::size_t k = 0; k + 1 < Way.size(); ++k)
|
||||
if (Way[k + 1].track != Way[k].track && Way[k].track->eType == tt_Normal && std::abs(Way[k].distance - Wanted) < miss)
|
||||
{
|
||||
miss = std::abs(Way[k].distance - Wanted);
|
||||
best = static_cast<int>(k);
|
||||
Joint = true;
|
||||
}
|
||||
if (best >= 0)
|
||||
return best;
|
||||
for (std::size_t k = 0; k < Way.size(); ++k)
|
||||
if (Way[k].track->eType == tt_Normal && end_gap(*Way[k].track, Way[k].point) > 0.5 && std::abs(Way[k].distance - Wanted) < miss)
|
||||
{
|
||||
miss = std::abs(Way[k].distance - Wanted);
|
||||
best = static_cast<int>(k);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
srk_tool::shp_state srk_tool::head_check::shp_of() const
|
||||
{
|
||||
if (shp < 0.0)
|
||||
return shp_state::needless;
|
||||
if (shp_found < 0.0)
|
||||
return shp_short ? shp_state::beyond : shp_state::missing;
|
||||
return std::abs(shp_found - shp) > kShpTolerance ? shp_state::off : shp_state::placed;
|
||||
}
|
||||
|
||||
void srk_tool::load()
|
||||
{
|
||||
if (m_loaded)
|
||||
@@ -950,7 +1012,7 @@ void srk_tool::render_options()
|
||||
ImGui::Spacing();
|
||||
gesture_rows({{"LMB on a switch", "opens its station"}});
|
||||
if (false == m_status.empty())
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", m_status.c_str());
|
||||
ImGui::TextColored(kDoubtful, "%s", m_status.c_str());
|
||||
ImGui::Spacing();
|
||||
render_found();
|
||||
return;
|
||||
@@ -1077,25 +1139,16 @@ void srk_tool::render_options()
|
||||
"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");
|
||||
step_heading(5, STR_C("SHP"));
|
||||
std::size_t needed{0};
|
||||
std::size_t found{0};
|
||||
std::size_t off{0};
|
||||
std::size_t nowhere{0};
|
||||
std::array<std::size_t, 5> states{};
|
||||
for (auto const &head : m_heads)
|
||||
if (head.shp >= 0.0)
|
||||
{
|
||||
++needed;
|
||||
if (head.shp_found >= 0.0)
|
||||
{
|
||||
++found;
|
||||
if (std::abs(head.shp_found - head.shp) > kShpTolerance)
|
||||
++off;
|
||||
}
|
||||
else if (head.shp_short)
|
||||
++nowhere;
|
||||
}
|
||||
ImGui::BeginDisabled(found + nowhere == needed);
|
||||
if (ImGui::Button(format("%s (%zu)###srkshp", STR_C("Place the SHP resonators"), needed - found - nowhere).c_str(), ImVec2(-1.0f, 0.0f)))
|
||||
++states[static_cast<std::size_t>(head.shp_of())];
|
||||
auto const of = [&](shp_state const State) { return states[static_cast<std::size_t>(State)]; };
|
||||
auto const needed{m_heads.size() - of(shp_state::needless)};
|
||||
auto const found{of(shp_state::off) + of(shp_state::placed)};
|
||||
auto const off{of(shp_state::off)};
|
||||
auto const nowhere{of(shp_state::beyond)};
|
||||
ImGui::BeginDisabled(of(shp_state::missing) == 0);
|
||||
if (ImGui::Button(format("%s (%zu)###srkshp", STR_C("Place the SHP resonators"), of(shp_state::missing)).c_str(), ImVec2(-1.0f, 0.0f)))
|
||||
set_shp();
|
||||
ImGui::EndDisabled();
|
||||
item_tooltip("Places the SHP track resonators the signals checked lack, rezonator.inc, as PKP PLK places them: 200 m before an entry "
|
||||
@@ -1122,7 +1175,7 @@ void srk_tool::render_options()
|
||||
ImGui::EndTable();
|
||||
}
|
||||
if (false == m_status.empty())
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", m_status.c_str());
|
||||
ImGui::TextColored(kDoubtful, "%s", m_status.c_str());
|
||||
ImGui::Spacing();
|
||||
m_length_hover = -1;
|
||||
if (ImGui::CollapsingHeader(format("%s (%zu)###srklengths", STR_C("Track lengths"), m_lengths.size()).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
@@ -1354,7 +1407,7 @@ void srk_tool::render_lengths()
|
||||
}
|
||||
ImGui::TextDisabled(STR_C("Construction length %.0f m: between the switches at its ends, the switches within it left out"), track.construction);
|
||||
if (std::abs(track.ways[0].length - track.ways[1].length) > kUnequal)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", STR_C("The two ways differ: their trains stop on other stretches of the track, between other switches or signals"));
|
||||
ImGui::TextColored(kDoubtful, "%s", STR_C("The two ways differ: their trains stop on other stretches of the track, between other switches or signals"));
|
||||
ImGui::TextDisabled("%s", STR_C("LMB: show it"));
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
@@ -1415,7 +1468,7 @@ void srk_tool::render_heads()
|
||||
for (std::size_t index = 0; index < m_heads.size(); ++index)
|
||||
{
|
||||
auto const &head{m_heads[index]};
|
||||
if (head.station || false == head.fits || false == head.problems.empty() || (head.shp >= 0.0 && (head.shp_found < 0.0 || std::abs(head.shp_found - head.shp) > kShpTolerance)))
|
||||
if (head.station || false == head.fits || false == head.problems.empty() || (head.shp_of() != shp_state::needless && head.shp_of() != shp_state::placed))
|
||||
rows.push_back(index);
|
||||
else
|
||||
++fine;
|
||||
@@ -1474,26 +1527,26 @@ void srk_tool::render_heads()
|
||||
ImGui::TextUnformatted(format(STR_C("Needs: %s"), need_text(need).c_str()).c_str());
|
||||
}
|
||||
if (head.shortened > 0)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", format(STR_C("The next signal stands nearer than the braking distance: with it at stop this one slows the trains to %d km/h, Ie-4 § 8 ust. 5"), head.shortened).c_str());
|
||||
ImGui::TextColored(kDoubtful, "%s", format(STR_C("The next signal stands nearer than the braking distance: with it at stop this one slows the trains to %d km/h, Ie-4 § 8 ust. 5"), head.shortened).c_str());
|
||||
if (head.indicator)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", STR_C("Give it a W21 indicator \"14\": 140 km/h with the next signal at stop, Ie-4 § 8 ust. 5"));
|
||||
ImGui::TextColored(kDoubtful, "%s", STR_C("Give it a W21 indicator \"14\": 140 km/h with the next signal at stop, Ie-4 § 8 ust. 5"));
|
||||
if (head.lamps.empty() && head.kind != "warning")
|
||||
ImGui::TextDisabled("%s", STR_C("A semaphore with arms: its lights aren't checked"));
|
||||
else if (false == head.fits && head.fit.empty())
|
||||
ImGui::TextColored(kWrong, "%s", STR_C("No template of its kind and mount has these lights"));
|
||||
else if (false == head.fits)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", format(STR_C("Its lights don't show all of it: %s does"), head.fit.c_str()).c_str());
|
||||
ImGui::TextColored(kDoubtful, "%s", format(STR_C("Its lights don't show all of it: %s does"), head.fit.c_str()).c_str());
|
||||
else if (head.more)
|
||||
ImGui::TextDisabled("%s", format(STR_C("It has more lights than it needs: %s will do"), head.fit.c_str()).c_str());
|
||||
for (auto const &problem : head.problems)
|
||||
ImGui::TextColored(kWrong, "%s", problem.c_str());
|
||||
if (head.shp >= 0.0)
|
||||
if (auto const state{head.shp_of()}; state != shp_state::needless)
|
||||
{
|
||||
auto const wanted{head.shp > 0.0 ? format(STR_C("its SHP resonator belongs %.0f m before it"), head.shp) : std::string{STR_C("its SHP resonator belongs at it, it tells of the next signal")}};
|
||||
if (head.shp_found < 0.0)
|
||||
ImGui::TextColored(kWrong, "%s", (wanted + ", " + (head.shp_short ? STR("the tracks before it end short of it") : STR("none stands"))).c_str());
|
||||
if (state == shp_state::missing || state == shp_state::beyond)
|
||||
ImGui::TextColored(kWrong, "%s", (wanted + ", " + (state == shp_state::beyond ? STR("the tracks before it end short of it") : STR("none stands"))).c_str());
|
||||
else
|
||||
ImGui::TextColored(std::abs(head.shp_found - head.shp) > kShpTolerance ? ImVec4(1.0f, 0.75f, 0.3f, 1.0f) : ImVec4(0.45f, 0.85f, 0.45f, 1.0f), "%s", (wanted + ", " + format(STR_C("its event %.0f m before it"), head.shp_found)).c_str());
|
||||
ImGui::TextColored(state == shp_state::off ? kDoubtful : kRight, "%s", (wanted + ", " + format(STR_C("its event %.0f m before it"), head.shp_found)).c_str());
|
||||
}
|
||||
ImGui::TextDisabled("%s", STR_C("LMB: fly to it"));
|
||||
ImGui::PopTextWrapPos();
|
||||
@@ -1518,25 +1571,25 @@ void srk_tool::render_heads()
|
||||
if (head.lamps.empty())
|
||||
ImGui::TextDisabled("-");
|
||||
else if (false == head.fits)
|
||||
ImGui::TextColored(head.fit.empty() ? kWrong : ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%s", head.fit.empty() ? STR_C("no template") : STR_C("lights missing"));
|
||||
ImGui::TextColored(head.fit.empty() ? kWrong : kDoubtful, "%s", head.fit.empty() ? STR_C("no template") : STR_C("lights missing"));
|
||||
else if (head.more)
|
||||
ImGui::TextDisabled("%s", STR_C("more than needed"));
|
||||
else
|
||||
ImGui::TextColored(ImVec4(0.45f, 0.85f, 0.45f, 1.0f), "%s", STR_C("fits"));
|
||||
ImGui::TextColored(kRight, "%s", STR_C("fits"));
|
||||
if (false == head.problems.empty())
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(kWrong, "%s", STR_C("too near"));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (head.shp < 0.0)
|
||||
ImGui::TextDisabled("-");
|
||||
else if (head.shp_found < 0.0)
|
||||
ImGui::TextColored(kWrong, "%s", head.shp_short ? STR_C("no track") : STR_C("none"));
|
||||
else if (std::abs(head.shp_found - head.shp) > kShpTolerance)
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.3f, 1.0f), "%.0f m", head.shp_found);
|
||||
else
|
||||
ImGui::TextColored(ImVec4(0.45f, 0.85f, 0.45f, 1.0f), "%s", head.shp > 0.0 ? format("%.0f m", head.shp_found).c_str() : STR_C("at it"));
|
||||
switch (head.shp_of())
|
||||
{
|
||||
case shp_state::needless: ImGui::TextDisabled("-"); break;
|
||||
case shp_state::missing: ImGui::TextColored(kWrong, "%s", STR_C("none")); break;
|
||||
case shp_state::beyond: ImGui::TextColored(kWrong, "%s", STR_C("no track")); break;
|
||||
case shp_state::off: ImGui::TextColored(kDoubtful, "%.0f m", head.shp_found); break;
|
||||
default: ImGui::TextColored(kRight, "%s", head.shp > 0.0 ? format("%.0f m", head.shp_found).c_str() : STR_C("at it")); break;
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
@@ -2274,7 +2327,6 @@ void srk_tool::set_lines()
|
||||
{
|
||||
m_status.clear();
|
||||
auto const stem{stem_of_open()};
|
||||
auto const &layout{*m_layout};
|
||||
std::vector<standing_signal> standing;
|
||||
m_signals.standing_signals(standing, true);
|
||||
std::vector<station::line> lines;
|
||||
@@ -2282,6 +2334,7 @@ void srk_tool::set_lines()
|
||||
std::vector<std::size_t> entry_standing;
|
||||
if (false == lines_of_open(standing, lines, entries, entry_standing, m_status))
|
||||
return;
|
||||
auto const &layout{*m_layout};
|
||||
// of each line, 1: the automatic block, placed on a double-track line only, 2: the automatic block on a single-track line, its
|
||||
// signals facing both ways on a track left as they stand, 0: the semi-automatic one
|
||||
std::vector<char> automatic(lines.size(), 0);
|
||||
@@ -2721,6 +2774,8 @@ void srk_tool::survey_signals()
|
||||
{
|
||||
m_heads.clear();
|
||||
m_heads_known = false;
|
||||
m_lines.clear();
|
||||
m_lines_problem = STR("Looking for the signal templates...");
|
||||
if (false == m_measured)
|
||||
measure({});
|
||||
return;
|
||||
@@ -3011,6 +3066,7 @@ void srk_tool::set_shp()
|
||||
taken.insert(ToLower(event.first));
|
||||
struct placing
|
||||
{
|
||||
std::string signal; // shown
|
||||
std::string name; // of the resonator, its event is <name>_shp
|
||||
TTrack *track{nullptr}; // the trains run into its event on, where a joint of the tracks lies
|
||||
TTrack *cut{nullptr}; // the track cut at the point, else
|
||||
@@ -3023,9 +3079,9 @@ void srk_tool::set_shp()
|
||||
std::vector<std::string> problems;
|
||||
for (auto const &head : m_heads)
|
||||
{
|
||||
if (head.shp < 0.0 || head.shp_found >= 0.0)
|
||||
if (head.shp_of() != shp_state::missing && head.shp_of() != shp_state::beyond)
|
||||
continue;
|
||||
if (head.shp_short)
|
||||
if (head.shp_of() == shp_state::beyond)
|
||||
{
|
||||
problems.push_back(format(STR_C("%s: the tracks before it end short of %.0f m"), head.name.c_str(), head.shp));
|
||||
continue;
|
||||
@@ -3045,29 +3101,8 @@ void srk_tool::set_shp()
|
||||
problems.push_back(format(STR_C("%s: the tracks before it end short of %.0f m"), head.name.c_str(), head.shp));
|
||||
continue;
|
||||
}
|
||||
// a joint of the tracks within the tolerance takes the event on the track the trains run into there, else the track is cut
|
||||
auto best{-1};
|
||||
auto joint{false};
|
||||
auto miss{kShpTolerance + 1e-6};
|
||||
for (std::size_t k = 0; k + 1 < way.size(); ++k)
|
||||
if (way[k + 1].track != way[k].track && way[k].track->eType == tt_Normal && std::abs(way[k].distance - head.shp) < miss)
|
||||
{
|
||||
miss = std::abs(way[k].distance - head.shp);
|
||||
best = static_cast<int>(k);
|
||||
joint = true;
|
||||
}
|
||||
if (best < 0)
|
||||
for (std::size_t k = 0; k < way.size(); ++k)
|
||||
{
|
||||
auto const &ends{way[k].track->m_paths.front().points};
|
||||
if (way[k].track->eType != tt_Normal || std::min(glm::distance(way[k].point, ends[segment_data::point::start]), glm::distance(way[k].point, ends[segment_data::point::end])) <= 0.5)
|
||||
continue;
|
||||
if (std::abs(way[k].distance - head.shp) < miss)
|
||||
{
|
||||
miss = std::abs(way[k].distance - head.shp);
|
||||
best = static_cast<int>(k);
|
||||
}
|
||||
}
|
||||
auto const best{resonator_at(way, head.shp, joint)};
|
||||
if (best < 0)
|
||||
{
|
||||
problems.push_back(format(STR_C("%s: no plain track within %.0f m of the place of its SHP resonator"), head.name.c_str(), kShpTolerance));
|
||||
@@ -3090,6 +3125,7 @@ void srk_tool::set_shp()
|
||||
for (int number = 2; taken.count(ToLower(name) + "_shp") > 0 && number < 100; ++number)
|
||||
name = found->name + "_rez" + std::to_string(number);
|
||||
taken.insert(ToLower(name) + "_shp");
|
||||
entry.signal = head.name;
|
||||
entry.name = name;
|
||||
entry.facing = at.facing;
|
||||
entry.point = at.point;
|
||||
@@ -3132,8 +3168,7 @@ void srk_tool::set_shp()
|
||||
if (entry.cut == nullptr)
|
||||
continue;
|
||||
auto *track{piece_at(entry.cut, entry.point)};
|
||||
auto const &ends{track->m_paths.front().points};
|
||||
if (std::min(glm::distance(entry.point, ends[segment_data::point::start]), glm::distance(entry.point, ends[segment_data::point::end])) <= 0.3)
|
||||
if (end_gap(*track, entry.point) <= 0.3)
|
||||
continue;
|
||||
if (captured.insert(track).second)
|
||||
before.emplace_back(track, editor_track::capture(*track));
|
||||
@@ -3152,6 +3187,12 @@ void srk_tool::set_shp()
|
||||
for (auto const &entry : places)
|
||||
{
|
||||
auto *track{entry.track != nullptr ? entry.track : piece_at(entry.cut, entry.inside)};
|
||||
// the trains run into the track at the point: at the start of its path running towards its end
|
||||
if (glm::distance(track->m_paths.front().points[entry.facing > 0 ? segment_data::point::start : segment_data::point::end], entry.point) > 1.0)
|
||||
{
|
||||
problems.push_back(format(STR_C("%s: the track couldn't be cut at the place of its SHP resonator"), entry.signal.c_str()));
|
||||
continue;
|
||||
}
|
||||
if (captured.insert(track).second)
|
||||
before.emplace_back(track, editor_track::capture(*track));
|
||||
editor_track::events(*track, entry.facing > 0 ? 2 : 1).emplace_back(ToLower(entry.name) + "_shp", nullptr);
|
||||
@@ -3167,13 +3208,14 @@ void srk_tool::set_shp()
|
||||
changes.others.push_back(std::move(item));
|
||||
}
|
||||
std::string error;
|
||||
auto const placed{changes.others.size()};
|
||||
m_signals.signal_batch(changes, std::move(before), std::move(created), error);
|
||||
if (false == error.empty())
|
||||
{
|
||||
m_status = format(STR_C("The SHP resonators couldn't be placed: %s"), error.c_str());
|
||||
m_status = format(STR_C("The SHP resonators couldn't be placed: %s. Ctrl+Z takes back the tracks cut"), error.c_str());
|
||||
return;
|
||||
}
|
||||
m_status = format(STR_P("%zu SHP resonator placed", "%zu SHP resonators placed", places.size()), places.size()) + ", " + format(STR_P("%zu track cut", "%zu tracks cut", cuts), cuts) + ". " + STR("Ctrl+Z takes it back, the resonators work after the scenery is saved and opened again");
|
||||
m_status = format(STR_P("%zu SHP resonator placed", "%zu SHP resonators placed", placed), placed) + ", " + format(STR_P("%zu track cut", "%zu tracks cut", cuts), cuts) + ". " + STR("Ctrl+Z takes it back, the resonators work after the scenery is saved and opened again");
|
||||
for (auto const &problem : problems)
|
||||
m_status += "\n" + problem;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,15 @@ class srk_tool final : public editor_tool
|
||||
int m_length_hover{-1}; // of the lengths, the row under the mouse
|
||||
int m_length_canvas{-1}; // of the lengths, of the track under the mouse in the schematic
|
||||
int m_length_shown{-1}; // of the lengths, the one drawn: of the row or the track under the mouse, else of the track selected
|
||||
// how the SHP track resonator of a signal stands
|
||||
enum class shp_state
|
||||
{
|
||||
needless, // the signal needs none
|
||||
missing,
|
||||
beyond, // missing, the tracks before the signal end short of its place
|
||||
off, // farther from its place than allowed
|
||||
placed
|
||||
};
|
||||
// a signal of the station or of its lines, its lights as the routes of its trains need them: Ie-1, Ie-4 § 8
|
||||
struct head_check
|
||||
{
|
||||
@@ -153,6 +162,7 @@ class srk_tool final : public editor_tool
|
||||
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
|
||||
shp_state shp_of() const;
|
||||
};
|
||||
std::vector<head_check> m_heads;
|
||||
bool m_heads_known{false}; // the templates found
|
||||
|
||||
@@ -11233,8 +11233,11 @@ 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 "The SHP resonators couldn't be placed: %s. Ctrl+Z takes back the tracks cut"
|
||||
msgstr "Nie udało się postawić rezonatorów SHP: %s. Ctrl+Z cofa przecięcie torów"
|
||||
|
||||
msgid "%s: the track couldn't be cut at the place of its SHP resonator"
|
||||
msgstr "%s: nie udało się przeciąć toru w miejscu rezonatora SHP"
|
||||
|
||||
msgid "at it"
|
||||
msgstr "przy nim"
|
||||
|
||||
Reference in New Issue
Block a user