aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2018-06-19 19:50:11 +0200
committerorwell96 <orwell@bleipb.de>2018-06-19 19:50:11 +0200
commit65675664e3cdf3328b89b4bdc22cc07c21be3a56 (patch)
tree4519b5d3fd9f13c0f554eba7e88a7e3bcdc36616
parent08ac0f9c05c4623a2783749b1dee2dafa234cee6 (diff)
downloadadvtrains-65675664e3cdf3328b89b4bdc22cc07c21be3a56.tar.gz
advtrains-65675664e3cdf3328b89b4bdc22cc07c21be3a56.tar.bz2
advtrains-65675664e3cdf3328b89b4bdc22cc07c21be3a56.zip
Interlocking: Create demo signals, signal API and model for TCB configurer node
-rw-r--r--advtrains_interlocking/database.lua18
-rw-r--r--advtrains_interlocking/demosignals.lua89
-rw-r--r--advtrains_interlocking/depends.txt1
-rw-r--r--advtrains_interlocking/init.lua10
-rw-r--r--advtrains_interlocking/models/at_il_tcb_node.obj248
-rw-r--r--advtrains_interlocking/signal_api.lua75
-rw-r--r--advtrains_interlocking/textures/at_il_signal_asp_danger.pngbin0 -> 247 bytes
-rw-r--r--advtrains_interlocking/textures/at_il_signal_asp_free.pngbin0 -> 245 bytes
-rw-r--r--advtrains_interlocking/textures/at_il_signal_asp_slow.pngbin0 -> 245 bytes
-rw-r--r--advtrains_interlocking/textures/at_il_signal_off.pngbin0 -> 236 bytes
-rw-r--r--advtrains_interlocking/textures/at_il_tcb_marker.pngbin0 -> 308 bytes
-rw-r--r--advtrains_interlocking/textures/at_il_tcb_node.pngbin0 -> 279 bytes
-rw-r--r--assets/at_il_tcb_node.blendbin0 -> 483100 bytes
13 files changed, 437 insertions, 4 deletions
diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua
index 7a49383..61bf5ad 100644
--- a/advtrains_interlocking/database.lua
+++ b/advtrains_interlocking/database.lua
@@ -5,8 +5,7 @@ The interlocking system is based on track circuits.
Track circuit breaks must be manually set by the user. Signals must be assigned to track circuit breaks and to a direction(connid).
To simplify the whole system, there is no overlap.
== Trains ==
-A train always reserves the space between two signals facing it. All track circuits in this space
-have a reservation entry TRAIN with the train's ID
+Trains always occupy certain track circuits. These are shown red in the signalbox view (TRAIN occupation entry).
== Database storage ==
The things that are actually saved are the Track Circuit Breaks. Each TCB holds a list of the TCBs that are adjacent in each direction.
TC occupation/state is then saved inside each (TCB,Direction) and held in sync across all TCBs adjacent to this one. If something should not be in sync,
@@ -21,6 +20,8 @@ A track circuit does not have a state as such, but has more or less a list of "r
type can be one of these:
TRAIN See Trains obove
ROUTE Route set from a signal, but no train has yet passed that signal.
+Not implemented (see note by reversible): OWNED - former ROUTE segments that a train has begun passing (train_id assigned)
+ - Space behind a train up to the next signal, when a TC is set as REVERSIBLE
Certain TCs can be marked as "allow call-on".
== Route setting: ==
Routes are set from a signal (the entry signal) to another signal facing the same direction (the exit signal)
@@ -35,8 +36,17 @@ Apart from this, we need to set turnouts
It will be necessary to join and split trains using call-on routes. A call-on route may be set when:
- there are no ROUTE reservations
- there are TRAIN reservations only inside TCs that have "allow call-on" set
-
-
+== TC Properties ==
+Note: Reversible property will not be implemented, assuming everything as non-rev.
+This is sufficient to cover all use cases, and is done this way in reality.
+ REVERSIBLE - Whether trains are allowed to reverse while on track circuit
+ This property is supposed to be set for station tracks, where there is a signal at each end, and for sidings.
+ It should in no case be set for TCs covering turnouts, or for main running lines.
+ When a TC is not set as reversible, the OWNED status is cleared from the TC right after the train left it,
+ to allow other trains to pass it.
+ If it is set reversible, interlocking will keep the OWNED state behind the train up to the next signal, clearing it
+ as soon as the train passes another signal or enters a non-reversible section.
+CALL_ON_ALLOWED - Whether this TC being blocked (TRAIN or ROUTE) does not prevent shunt routes being set through this TC
== More notes ==
- It may not be possible to switch turnouts when their TC has any state entry
diff --git a/advtrains_interlocking/demosignals.lua b/advtrains_interlocking/demosignals.lua
new file mode 100644
index 0000000..8320afb
--- /dev/null
+++ b/advtrains_interlocking/demosignals.lua
@@ -0,0 +1,89 @@
+-- Demonstration signals
+-- Those can display the 3 main aspects of Ks signals
+
+
+minetest.register_node("advtrains_interlocking:ds_danger", {
+ description = "Demo signal at Danger",
+ tiles = {"at_il_signal_asp_danger.png"},
+ groups = {
+ cracky = 3,
+ advtrains_signal = 1,
+ save_in_at_nodedb = 1,
+ },
+ sounds = default.node_sound_stone_defaults(),
+ advtrains = {
+ set_aspect = function(pos, node, asp)
+ if asp.main.free then
+ if asp.dst.free and asp.main.speed > 50 then
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"})
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"})
+ end
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"})
+ end
+ local meta = minetest.get_meta(pos)
+ if meta then
+ meta:set_string("infotext", minetest.serialize(asp))
+ end
+ end
+ },
+ on_rightclick = advtrains.interlocking.signal_rc_handler
+})
+minetest.register_node("advtrains_interlocking:ds_free", {
+ description = "Demo signal at Free",
+ tiles = {"at_il_signal_asp_free.png"},
+ groups = {
+ cracky = 3,
+ advtrains_signal = 1,
+ save_in_at_nodedb = 1,
+ },
+ sounds = default.node_sound_stone_defaults(),
+ advtrains = {
+ set_aspect = function(pos, node, asp)
+ if asp.main.free then
+ if asp.dst.free and asp.main.speed > 50 then
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"})
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"})
+ end
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"})
+ end
+ local meta = minetest.get_meta(pos)
+ if meta then
+ meta:set_string("infotext", minetest.serialize(asp))
+ end
+ end
+ },
+ on_rightclick = advtrains.interlocking.signal_rc_handler
+})
+minetest.register_node("advtrains_interlocking:ds_slow", {
+ description = "Demo signal at Slow",
+ tiles = {"at_il_signal_asp_slow.png"},
+ groups = {
+ cracky = 3,
+ advtrains_signal = 1,
+ save_in_at_nodedb = 1,
+ },
+ sounds = default.node_sound_stone_defaults(),
+ advtrains = {
+ set_aspect = function(pos, node, asp)
+ if asp.main.free then
+ if asp.dst.free and asp.main.speed > 50 then
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"})
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"})
+ end
+ else
+ advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"})
+ end
+ local meta = minetest.get_meta(pos)
+ if meta then
+ meta:set_string("infotext", minetest.serialize(asp))
+ end
+ end
+ },
+ on_rightclick = advtrains.interlocking.signal_rc_handler
+})
+
diff --git a/advtrains_interlocking/depends.txt b/advtrains_interlocking/depends.txt
new file mode 100644
index 0000000..6f00bf6
--- /dev/null
+++ b/advtrains_interlocking/depends.txt
@@ -0,0 +1 @@
+advtrains \ No newline at end of file
diff --git a/advtrains_interlocking/init.lua b/advtrains_interlocking/init.lua
index e69de29..ab79573 100644
--- a/advtrains_interlocking/init.lua
+++ b/advtrains_interlocking/init.lua
@@ -0,0 +1,10 @@
+-- Advtrains interlocking system
+-- See database.lua for a detailed explanation
+
+advtrains.interlocking = {}
+
+local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELIM
+
+dofile(modpath.."database.lua")
+dofile(modpath.."signal_api.lua")
+dofile(modpath.."demosignals.lua")
diff --git a/advtrains_interlocking/models/at_il_tcb_node.obj b/advtrains_interlocking/models/at_il_tcb_node.obj
new file mode 100644
index 0000000..bb6aab5
--- /dev/null
+++ b/advtrains_interlocking/models/at_il_tcb_node.obj
@@ -0,0 +1,248 @@
+# Blender v2.76 (sub 0) OBJ File: ''
+# www.blender.org
+mtllib at_il_tcb_node.mtl
+o Cube
+v 0.038370 -0.500000 -0.038370
+v 0.038370 -0.500000 0.038370
+v -0.038370 -0.500000 0.038370
+v -0.038370 -0.500000 -0.038370
+v 0.038370 0.098086 -0.038370
+v 0.038370 0.098086 0.038370
+v -0.038370 0.098086 0.038370
+v -0.038370 0.098086 -0.038370
+v -0.182395 0.065479 0.099357
+v -0.182395 0.182395 0.099357
+v -0.182395 0.065479 -0.171034
+v -0.182395 0.182395 -0.171034
+v 0.182395 0.065479 0.099357
+v 0.182395 0.182395 0.099357
+v 0.182395 0.065479 -0.171034
+v 0.182395 0.182395 -0.171034
+v -0.112374 0.070035 -0.139406
+v -0.112374 -0.500000 -0.139406
+v 0.112189 -0.500000 -0.139406
+v 0.112189 0.070035 -0.139406
+v 0.122883 -0.500000 -0.137278
+v 0.122883 0.070035 -0.137278
+v 0.131950 -0.500000 -0.131220
+v 0.131950 0.070035 -0.131220
+v 0.138008 -0.500000 -0.122154
+v 0.138008 0.070035 -0.122154
+v 0.140135 -0.500000 -0.111459
+v 0.140135 0.070035 -0.111459
+v 0.138008 -0.500000 -0.100765
+v 0.138008 0.070035 -0.100765
+v 0.131950 -0.500000 -0.091698
+v 0.131950 0.070035 -0.091698
+v 0.122883 -0.500000 -0.085640
+v 0.122883 0.070035 -0.085640
+v 0.112189 -0.500000 -0.083513
+v 0.112189 0.070035 -0.083513
+v 0.101494 -0.500000 -0.085640
+v 0.101494 0.070035 -0.085640
+v 0.092428 -0.500000 -0.091698
+v 0.092428 0.070035 -0.091698
+v 0.086370 -0.500000 -0.100765
+v 0.086370 0.070035 -0.100765
+v 0.084242 -0.500000 -0.111459
+v 0.084242 0.070035 -0.111459
+v 0.086370 -0.500000 -0.122154
+v 0.086370 0.070035 -0.122154
+v 0.092428 -0.500000 -0.131220
+v 0.092428 0.070035 -0.131220
+v 0.101494 -0.500000 -0.137278
+v 0.101494 0.070035 -0.137278
+v -0.101679 -0.500000 -0.137278
+v -0.101679 0.070035 -0.137278
+v -0.092613 -0.500000 -0.131220
+v -0.092613 0.070035 -0.131220
+v -0.086555 -0.500000 -0.122154
+v -0.086555 0.070035 -0.122154
+v -0.084428 -0.500000 -0.111459
+v -0.084428 0.070035 -0.111459
+v -0.086555 -0.500000 -0.100765
+v -0.086555 0.070035 -0.100765
+v -0.092613 -0.500000 -0.091698
+v -0.092613 0.070035 -0.091698
+v -0.101679 -0.500000 -0.085640
+v -0.101679 0.070035 -0.085640
+v -0.112374 -0.500000 -0.083513
+v -0.112374 0.070035 -0.083513
+v -0.123069 -0.500000 -0.085640
+v -0.123069 0.070035 -0.085640
+v -0.132135 -0.500000 -0.091698
+v -0.132135 0.070035 -0.091698
+v -0.138193 -0.500000 -0.100765
+v -0.138193 0.070035 -0.100765
+v -0.140320 -0.500000 -0.111459
+v -0.140320 0.070035 -0.111459
+v -0.138193 -0.500000 -0.122154
+v -0.138193 0.070035 -0.122154
+v -0.132135 -0.500000 -0.131220
+v -0.132135 0.070035 -0.131220
+v -0.123069 -0.500000 -0.137278
+v -0.123069 0.070035 -0.137278
+vt 0.876073 0.266665
+vt 0.876073 0.977812
+vt 0.784827 0.977812
+vt 0.784827 0.266665
+vt 0.693582 0.977812
+vt 0.693582 0.266665
+vt 0.602336 0.977812
+vt 0.602336 0.266665
+vt 0.967319 0.266665
+vt 0.967319 0.977812
+vt 0.147929 0.032040
+vt 0.469434 0.032040
+vt 0.469434 0.171057
+vt 0.147929 0.171057
+vt 0.903184 0.032040
+vt 0.903184 0.171057
+vt 0.147929 0.032751
+vt 0.469434 0.032751
+vt 0.469434 0.171768
+vt 0.147929 0.171768
+vt 0.903184 0.032751
+vt 0.903183 0.171768
+vt 0.263807 0.270252
+vt 0.585312 0.270252
+vt 0.585312 0.704001
+vt 0.263807 0.704001
+vt 0.584297 0.703059
+vt 0.262792 0.703059
+vt 0.262793 0.269309
+vt 0.584297 0.269309
+vt 0.108472 0.980897
+vt 0.108473 0.303114
+vt 0.121438 0.303114
+vt 0.121438 0.980897
+vt 0.081877 0.980125
+vt 0.081879 0.302342
+vt 0.094844 0.302342
+vt 0.094843 0.980125
+vt 0.095507 0.980897
+vt 0.095508 0.303114
+vt 0.107809 0.302342
+vt 0.107808 0.980125
+vt 0.082541 0.980897
+vt 0.082543 0.303114
+vt 0.120774 0.302342
+vt 0.120774 0.980125
+vt 0.069575 0.980897
+vt 0.069577 0.303114
+vt 0.133739 0.302342
+vt 0.133740 0.980125
+vt 0.056609 0.980897
+vt 0.056612 0.303114
+vt 0.146705 0.302342
+vt 0.146706 0.980125
+vt 0.043643 0.980897
+vt 0.043647 0.303114
+vt 0.159670 0.302342
+vt 0.159672 0.980125
+vt 0.030677 0.980897
+vt 0.030682 0.303113
+vt 0.172635 0.302342
+vt 0.172638 0.980125
+vt 0.017711 0.980897
+vt 0.017717 0.303113
+vt 0.185600 0.302342
+vt 0.185604 0.980125
+vt 0.212200 0.980896
+vt 0.212195 0.303113
+vt 0.225160 0.303113
+vt 0.225166 0.980896
+vt 0.198565 0.302342
+vt 0.198570 0.980125
+vt 0.199234 0.980897
+vt 0.199230 0.303114
+vt 0.211531 0.302342
+vt 0.211536 0.980125
+vt 0.186268 0.980897
+vt 0.186264 0.303114
+vt 0.224496 0.302342
+vt 0.224502 0.980125
+vt 0.173302 0.980897
+vt 0.173299 0.303114
+vt 0.017047 0.980125
+vt 0.017052 0.302342
+vt 0.030018 0.302342
+vt 0.030013 0.980125
+vt 0.134403 0.303114
+vt 0.134404 0.980897
+vt 0.160336 0.980897
+vt 0.160334 0.303114
+vt 0.042983 0.302342
+vt 0.042979 0.980125
+vt 0.147369 0.303114
+vt 0.147370 0.980897
+vt 0.055948 0.302342
+vt 0.055945 0.980125
+vt 0.068911 0.980125
+vt 0.068913 0.302342
+vn 1.000000 0.000000 0.000000
+vn -0.000000 -0.000000 1.000000
+vn -1.000000 -0.000000 -0.000000
+vn 0.000000 0.000000 -1.000000
+vn 0.000000 -1.000000 0.000000
+vn 0.000000 1.000000 0.000000
+vn -0.831500 0.000000 -0.555600
+vn 0.195100 0.000000 -0.980800
+vn -0.980800 0.000000 -0.195100
+vn 0.555600 0.000000 -0.831500
+vn -0.980800 0.000000 0.195100
+vn 0.831500 0.000000 -0.555600
+vn -0.831500 0.000000 0.555600
+vn 0.980800 0.000000 -0.195100
+vn -0.555600 0.000000 0.831500
+vn 0.980800 0.000000 0.195100
+vn -0.195100 0.000000 0.980800
+vn 0.831500 0.000000 0.555600
+vn 0.195100 0.000000 0.980800
+vn 0.555600 0.000000 0.831500
+vn -0.555600 0.000000 -0.831500
+vn -0.195100 0.000000 -0.980800
+usemtl Material
+s off
+f 1/1/1 5/2/1 6/3/1 2/4/1
+f 2/4/2 6/3/2 7/5/2 3/6/2
+f 3/6/3 7/5/3 8/7/3 4/8/3
+f 5/2/4 1/1/4 4/9/4 8/10/4
+f 10/11/3 12/12/3 11/13/3 9/14/3
+f 12/12/4 16/15/4 15/16/4 11/13/4
+f 16/17/1 14/18/1 13/19/1 15/20/1
+f 14/18/2 10/21/2 9/22/2 13/19/2
+f 9/23/5 11/24/5 15/25/5 13/26/5
+f 14/27/6 16/28/6 12/29/6 10/30/6
+f 75/31/7 76/32/7 78/33/7 77/34/7
+f 19/35/8 20/36/8 22/37/8 21/38/8
+f 73/39/9 74/40/9 76/32/9 75/31/9
+f 21/38/10 22/37/10 24/41/10 23/42/10
+f 71/43/11 72/44/11 74/40/11 73/39/11
+f 23/42/12 24/41/12 26/45/12 25/46/12
+f 69/47/13 70/48/13 72/44/13 71/43/13
+f 25/46/14 26/45/14 28/49/14 27/50/14
+f 67/51/15 68/52/15 70/48/15 69/47/15
+f 27/50/16 28/49/16 30/53/16 29/54/16
+f 65/55/17 66/56/17 68/52/17 67/51/17
+f 29/54/18 30/53/18 32/57/18 31/58/18
+f 63/59/19 64/60/19 66/56/19 65/55/19
+f 31/58/20 32/57/20 34/61/20 33/62/20
+f 61/63/20 62/64/20 64/60/20 63/59/20
+f 33/62/19 34/61/19 36/65/19 35/66/19
+f 59/67/18 60/68/18 62/69/18 61/70/18
+f 35/66/17 36/65/17 38/71/17 37/72/17
+f 57/73/16 58/74/16 60/68/16 59/67/16
+f 37/72/15 38/71/15 40/75/15 39/76/15
+f 55/77/14 56/78/14 58/74/14 57/73/14
+f 39/76/13 40/75/13 42/79/13 41/80/13
+f 53/81/12 54/82/12 56/78/12 55/77/12
+f 41/83/11 42/84/11 44/85/11 43/86/11
+f 77/34/21 78/33/21 80/87/21 79/88/21
+f 51/89/10 52/90/10 54/82/10 53/81/10
+f 43/86/9 44/85/9 46/91/9 45/92/9
+f 79/88/22 80/87/22 17/93/22 18/94/22
+f 18/94/8 17/93/8 52/90/8 51/89/8
+f 45/92/7 46/91/7 48/95/7 47/96/7
+f 49/97/22 50/98/22 20/36/22 19/35/22
+f 47/96/21 48/95/21 50/98/21 49/97/21
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
new file mode 100644
index 0000000..e072273
--- /dev/null
+++ b/advtrains_interlocking/signal_api.lua
@@ -0,0 +1,75 @@
+-- Signal API implementation
+
+
+--[[ Signal aspect table:
+asp = {
+ main = {
+ free = <boolean>,
+ speed = <int km/h>,
+ },
+ shunt = {
+ free = <boolean>,
+ }
+ dst = {
+ free = <boolean>,
+ speed = <int km/h>,
+ }
+ info = {
+ call_on = <boolean>, -- Call-on route, expect train in track ahead
+ dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper)
+ }
+}
+Signals API:
+groups = {
+ advtrains_signal = 1,
+ save_in_at_nodedb = 1,
+}
+advtrains = {
+ function set_aspect(pos, node, asp)
+ ...
+ end
+}
+on_rightclick = advtrains.interlocking.signal_rc_handler
+
+]]--
+
+function advtrains.interlocking.signal_set_aspect(pos, asp)
+ local node=advtrains.ndb.get_node(pos)
+ local ndef=minetest.registered_nodes[node.name]
+ if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
+ ndef.advtrains.set_aspect(pos, node, asp)
+ end
+end
+
+function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, pointed_thing)
+ local pname = player:get_player_name()
+ minetest.show_formspec(pname, "at_il_sigasp_"..minetest.pos_to_string(pos), "field[aspect;Set Aspect (F/D)Speed(F/D)Speed(F/D);D0D0D]")
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ local pname = player:get_player_name()
+ local pts = string.match(formname, "^at_il_sigasp_(.+)$")
+ local pos
+ if pts then pos = minetest.string_to_pos(pts) end
+ if pos and fields.aspect then
+ local mfs, msps, dfs, dsps, shs = string.match(fields.aspect, "^([FD])([0-9]+)([FD])([0-9]+)([FD])$")
+ local asp = {
+ main = {
+ free = mfs=="F",
+ speed = tonumber(msps),
+ },
+ shunt = {
+ free = shs=="F",
+ },
+ dst = {
+ free = dfs=="F",
+ speed = tonumber(dsps),
+ },
+ info = {
+ call_on = false, -- Call-on route, expect train in track ahead
+ dead_end = false, -- Route ends on a dead end (e.g. bumper)
+ }
+ }
+ advtrains.interlocking.signal_set_aspect(pos, asp)
+ end
+end)
diff --git a/advtrains_interlocking/textures/at_il_signal_asp_danger.png b/advtrains_interlocking/textures/at_il_signal_asp_danger.png
new file mode 100644
index 0000000..fca786d
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_signal_asp_danger.png
Binary files differ
diff --git a/advtrains_interlocking/textures/at_il_signal_asp_free.png b/advtrains_interlocking/textures/at_il_signal_asp_free.png
new file mode 100644
index 0000000..e9d6e9c
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_signal_asp_free.png
Binary files differ
diff --git a/advtrains_interlocking/textures/at_il_signal_asp_slow.png b/advtrains_interlocking/textures/at_il_signal_asp_slow.png
new file mode 100644
index 0000000..9242bb3
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_signal_asp_slow.png
Binary files differ
diff --git a/advtrains_interlocking/textures/at_il_signal_off.png b/advtrains_interlocking/textures/at_il_signal_off.png
new file mode 100644
index 0000000..f9b1f79
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_signal_off.png
Binary files differ
diff --git a/advtrains_interlocking/textures/at_il_tcb_marker.png b/advtrains_interlocking/textures/at_il_tcb_marker.png
new file mode 100644
index 0000000..3efc38a
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_tcb_marker.png
Binary files differ
diff --git a/advtrains_interlocking/textures/at_il_tcb_node.png b/advtrains_interlocking/textures/at_il_tcb_node.png
new file mode 100644
index 0000000..d5f615f
--- /dev/null
+++ b/advtrains_interlocking/textures/at_il_tcb_node.png
Binary files differ
diff --git a/assets/at_il_tcb_node.blend b/assets/at_il_tcb_node.blend
new file mode 100644
index 0000000..9574b75
--- /dev/null
+++ b/assets/at_il_tcb_node.blend
Binary files differ