Итак, эта тема создана! Некоторые совершенно напрасно полагают, что поддержка безлеверных стрелок якобы может прекратиться в следующих версиях игры. К таким людям вопрос: если останется поддержка фикседтреков вообще, то с чего бы кому-то убирать поддержку стрелок в них? Вообще, фиксед-стрелки созданы вовсе не для того, чтобы делать крестовины и подвижные остряки, а, как и все фиксед-трэки, для того чтобы иметь длину и форму по госту. Можно вообще не делать видимую мешь для этой стрелки, оставить только точки привязки для рельсов и использовать тэг "useadjoiningtracktype 1". Можно делать стрелки с процедурными рельсами без собственной анимации. Анимация - это уже наш внешний костыль, и её поддержку, конечно же, тоже никто не сможет убрать, потому что это скрипты.
Я провёл некоторые эксперименты, сделал опытные образцы. По моим понятиям, вполне себе реально построить на таких стрелках любую маршрутизацию, только она, само собой, должна учитывать существование этих стрелок. Я предлагаю (или даже навязываю) свою помощь в доделке нашей сигналки, но нужно знать, что именно нужно уметь делать.
Если говорить о поддержке любого SceneryWithTrack, то в общем случае всё выглядит так:
1. Да
2. Да
3. В GSTrackSearch встречается SceneryWithTrack, от него получаются все привязанные стрелки. Перебираются все варианты направлений стрелок (если стрелок 4, то 2^4=16 вариантов) и GSTrackSearch каждый раз выходит из начальной точки куда глаза глядят. Так мы пройдём по всем отклонениям.
4. Во-первых, сам SceneryWithTrack можно идентифицировать по ID, так как он - MapObject и поэтому GameObject. Во-вторых, каждая привязанная к нему JunctionBase является на самом деле JunctionBaseGameObject. Можно кастовать, можно использовать GameObject JunctioBase::GetGameObject(). Ну а сохранять всё это в супе не составляет труда.
5. Пробежать элементарно, если есть список А сформировать его можно, стартуя GSTrackSearch от светофоров и ходя по всем отклонениям, см. пункт 3.
---------------------------------
Разработка и внедрение описанного требует времени и сил. Но при некоторых условиях всё можно сделать по-бырику. Если мы договоримся о некоторой унификации и , например, поддержке только специальных SceneryWithTrack, наследуемых от нашего класса и с нужными тэгами в конфиге, или иной способ, то всё ещё проще. Я могу предложить такую концепцию:
- Не вводится никаких специальных SceneryWithTrack, поддерживаются все.
- Картостроитель в редакторе размещает на single-track стороне каждого соединения путей SceneryWithTrack-объекта специальный левер.
- Этот левер является класса, пусть JunctionLinked isclass Junction. В этом классе существует объект JunctionBase LinkedJunctionBase и процедура JunctionBase GetAssotiatedJunctionBase(), которая выдаёт соответствующую стрелку из скенери. Также в этом классе есть процедуры int GetDirectionLinked(), SetDirectionLinked(int) и другие аналоги, которые вызывают соответствующие функции в ассоциированной стрелке.
- Маршрутизация, работая с Junction (встречая Junction в GStrackSearch или перебирая все Junction в каком-либо списке), всегда проверяет Junction на isclass JunctionLinked. Если да, то вместо него работать с JunctionLinked::GetAssotiatedJunctionBase() либо с GetDirectionLinked(), SetDirectionLinked() и аналогами из класса JunctionLinked. Маршрутизация хранит этот левер в своих базах, списках, супах, как обычное Junction. World::GetJunctionList() также будет его возвращать.
- Откуда левер возьмёт свой объект LinkedJunctionBase? Поиск делается элементарно, только один раз при первом вызове любой функции этого класса. Можно сделать поиск и в Init(), но не вижу смысла затягивать этим загрузку карт.
- Если SceneryWithTrack анимирован и хотел бы визуально соответствовать направлению своих стрелок, то он может ловить сообщения "Junction" "Toggled" или быть специального класса, скажем, SceneryWithJunctions. Наш левер, если просечёт принадлежность скенери к SceneryWithJunctions, вызовет в нём специально объявленную процедуру StateChanged(). Чтобы вообще устранить из скенери handler-ы сообщений (если в этом имеется выигрыш для производительности), то маршрутизация должна работать со стрелкой только через наш левер класса JunctionLinked, который всегда будет вызывать StateChanged() в скенери класса SceneryWithJunctions.
Приведённая концепция чем хороша:
- При размещении стрелок на карте не нужно прокладывать невидимые пути, остаётся только разместить левер (который будет не лишним в TANE, ведь он сможет ещё и содержать теги для раскачки поезда при проезде стрелки, это одна из фич Тани). Из-за отсутствия невидимых путей стрелки можно без страха и упрёка двигать и поворачивать.
- Стрелки липнут друг к другу, поэтому вообще не нужно при добавлении на карту даже поворачивать стрелку, её можно сразу соединить или строго выровнять по предыдущей. TSM стрелки у меня не обладают этим свойством, думаю потому что у них kind "buildable" вместо "fixed track".
- Поддержка этой системы маршрутизацией делается естественным образом и очень быстро.
- Если Scenery со стрелками наследован от SceneryWithJunctions, то можно обеспечить, чтобы наш левер считывал ещё и информацию о том, переведена стрелка на отклонение или прямо. В этом случае отпадает необходимость в маркерах отклонения. Но тогда и маршрутизация должна поддерживать этот момент.
По описанному методу уже есть наработки - собственно, левер, и несколько стрелок, в том числе английская. TrackSearch всё находит, проблем не заметил. Дам потестить.
----------------------------------------
Как я уже говорил, считаю, что маршрутизация могла бы поддерживать вообще любые SceneryWithTrack и без вспомогательных леверов. Но для этого нужно придумать и реализовать всякие алгоритмы, чем я мог бы заняться, если бы получил ТЗ от автора. А вышеописанную схему можно реализовать в короткие сроки.