17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-02 11:39:14 +01:00

Merge remote-tracking branch 'origin/feat/switch-blades' into feat/renderers-cleanup

This commit is contained in:
2026-10-29 23:55:04 +01:00
145 changed files with 36946 additions and 3791 deletions

View File

@@ -649,7 +649,10 @@ std::optional<modifier_shape::effect> modifier_shape::evaluate(double const X, d
auto const &b{points[i + 1].position};
auto const run{b - a};
auto const length{glm::dot(run, run)};
auto const t{length > 1e-12 ? std::clamp(glm::dot(point - a, run) / length, 0.0, 1.0) : 0.0};
auto const along{length > 1e-12 ? glm::dot(point - a, run) / length : 0.0};
if ((m_modifier.open_start && i == 0 && along < 0.0) || (m_modifier.open_end && i + 2 == points.size() && along > 1.0))
continue;
auto const t{std::clamp(along, 0.0, 1.0)};
auto const offset{glm::length(point - (a + run * t))};
if (offset < distance)
{
@@ -756,6 +759,10 @@ bool load_manifest(std::string const &Path, manifest &Manifest, std::string *Err
item.reach = reach.as<double>();
if (auto const rounding{entry["rounding"]})
item.rounding = rounding.as<double>();
if (auto const open{entry["open_start"]})
item.open_start = open.as<bool>();
if (auto const open{entry["open_end"]})
item.open_end = open.as<bool>();
if (auto const points{entry["points"]}; points && points.IsSequence())
for (auto const &point : points)
if (point.IsSequence() && point.size() >= 4)
@@ -856,6 +863,10 @@ bool save_manifest(std::string const &Path, manifest const &Manifest, std::strin
out << YAML::Key << "slope" << YAML::Value << item.slope;
out << YAML::Key << "reach" << YAML::Value << item.reach;
out << YAML::Key << "rounding" << YAML::Value << item.rounding;
if (item.open_start)
out << YAML::Key << "open_start" << YAML::Value << true;
if (item.open_end)
out << YAML::Key << "open_end" << YAML::Value << true;
out << YAML::Key << "points" << YAML::Value << YAML::BeginSeq;
for (auto const &point : item.points)
out << YAML::Flow << YAML::BeginSeq << point.position.x << point.position.y << point.formation << point.half_width << YAML::EndSeq;

View File

@@ -170,6 +170,10 @@ struct modifier
double slope{1.5}; // horizontal run of the slopes per metre of height
double reach{60.0}; // from the edge of the formation, where the slopes end even if they don't get to the ground
double rounding{1.5}; // over which the slopes bend into the formation and into the ground
// the formation and its slopes end square across the first or the last point, as against the abutment of a bridge or the
// portal of a tunnel; otherwise they go round it
bool open_start{false};
bool open_end{false};
std::vector<corridor_point> points;
// rectangle (x, z) the modifier can change the ground in

View File

@@ -567,7 +567,7 @@ void node_layers::stat(layer_handle const Layer)
}
// creates empty layer, included from specified one. returns: handle to the new layer, or null_handle with the explanation in Reason
layer_handle node_layers::create(std::string Name, layer_handle Parent, std::string &Reason)
layer_handle node_layers::create(std::string Name, layer_handle Parent, std::string &Reason, bool const Activate)
{
Parent = resolve(Parent);
if (false == valid(Parent) || layer(Parent).removed || layer(Parent).binary)
@@ -648,7 +648,10 @@ layer_handle node_layers::create(std::string Name, layer_handle Parent, std::str
created.context_begin = valid(anchor) ? layer(anchor).context_end : layer(Parent).context_insert();
created.context_end = created.context_begin;
active(layerhandle);
if (Activate)
{
active(layerhandle);
}
return layerhandle;
}
@@ -852,16 +855,18 @@ bool node_layers::pending() const
namespace
{
// marks of the lines the editor keeps track of
std::array<char const *, 6> const editormarks{"//$p", "//$h", "//$r", "//$b", "//$c", "//$o"};
std::array<char const *, 9> const editormarks{"//$p", "//$h", "//$r", "//$b", "//$c", "//$o", "//$s", "//$k", "//$a"};
// other tools put lines of their own after some of these marks: Rainsted its includes after //$r, the launcher the descriptions
// of the trainsets after //$o. The editor's lines of them are told by their first word
bool editor_line(char const *Mark, std::string const &Text)
{
static std::array<std::pair<std::string_view, std::array<std::string_view, 9>>, 3> const words{{
{"//$h", {"#", "alignment", "source", "ends", "norms", "pieces", "vertex", "element", "end"}},
static std::array<std::pair<std::string_view, std::array<std::string_view, 11>>, 5> const words{{
{"//$h", {"#", "alignment", "source", "ends", "norms", "pieces", "kept", "vertex", "click", "element", "end"}},
{"//$r", {"#", "switch", "slip", "crossing", "double", "connection"}},
{"//$o", {"on"}},
{"//$s", {"#", "station"}},
{"//$k", {"#", "mark", "via"}},
}};
auto const lookup{std::find_if(words.begin(), words.end(), [&](auto const &Entry) { return Entry.first == Mark; })};
if (lookup == words.end())
@@ -1099,13 +1104,17 @@ std::string node_layers::directive(instance_handle const Instance) const
}
// replaces the directive of specified include, the scenery file receives it on save
bool node_layers::modify(instance_handle const Instance, std::string const &Directive)
bool node_layers::modify(instance_handle const Instance, std::string const &Directive, std::string const &File)
{
if (false == tracked(Instance) || m_instances[Instance - 1].dead || Directive.empty())
{
return false;
}
m_instances[Instance - 1].directive = Directive;
if (false == File.empty())
{
m_instances[Instance - 1].file = &(*m_templates.emplace(File).first);
}
return true;
}

View File

@@ -302,8 +302,8 @@ class node_layers
void mark(layer_handle Layer, std::string const &Mark, std::vector<std::string> Lines);
// layer management. changes are applied to the scenery files by save()
// creates empty layer, included from specified one. returns: handle to the new layer, or null_handle with the explanation in Reason
layer_handle create(std::string Name, layer_handle Parent, std::string &Reason);
// creates empty layer, included from specified one, made active unless told otherwise. returns: handle to the new layer, or null_handle with the explanation in Reason
layer_handle create(std::string Name, layer_handle Parent, std::string &Reason, bool const Activate = true);
bool can_remove(layer_handle Layer, std::string &Reason) const;
// marks specified layer and the layers it includes as dropped from the scenery. their files are left on the disk
bool remove(layer_handle Layer);
@@ -343,7 +343,7 @@ class node_layers
// returns: empty text if the directive can't be read
std::string directive(instance_handle Instance) const;
// replaces the directive of specified include, the scenery file receives it on save. NOTE: the nodes aren't touched
bool modify(instance_handle Instance, std::string const &Directive);
bool modify(instance_handle Instance, std::string const &Directive, std::string const &File = {});
// takes the models specified include was loaded with out of the scene, once the editor shows its own in their place
void rebuilt(instance_handle Instance);
// true if specified node was replaced by the editor with a node showing the current state of its include