harset=UTF-8 Last-Modified: Mon, 02 Nov 2026 06:33:46 GMT Expires: Mon, 02 Nov 2026 06:38:46 GMT ars.lua « advtrains_interlocking - advtrains.git - Advtrains mod for minetest.
aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/ars.lua
blob: 393878ab87348ac29fbde0ed27742749d22bb431 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
1
std::string gob_cmd_set_texture_mod(const std::string &mod);

std::string gob_cmd_set_sprite(
	v2s16 p,
	u16 num_frames,
	f32 framelength,
	bool select_horiz_by_yawpitch
);

std::string gob_cmd_punched(s16 damage, s16 result_hp);

#include "itemgroup.h"
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);

std::string gob_cmd_update_physics_override(float physics_override_speed,
		float physics_override_jump, float physics_override_gravity, bool sneak, bool sneak_glitch);

std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend, bool frame_loop);

std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation);

std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation);

std::string gob_cmd_update_nametag_attributes(video::SColor color);

#endif

/a> 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
-- ars.lua
-- automatic routesetting

--[[
	The "ARS table" and its effects:
	Every route has (or can have) an associated ARS table:
	ars = {
		[n] = {
			ln = "<line>"			-- either line
			rc = "<routingcode>"	-- or routingcode
			tl = {min=1, max=2}		-- or train length in meters
			n = true/false -- true = logical not (matches everything that does not have this line/rc)
			conj = { -- and conjunction, optional. This must be true in addition to the main rule
				ln=... / rc=... / n=... -- like toplevel
				conj=... -- can be nested
						-- note that conj cannot have prio, in inherits the prio from main rule
			}
			prio = <num> -- optional, a priority number. If set, enables "multi-ARS" where train can wait for multiple routes at once
			-- or
			c="<a comment>"
		}
		default = true -- Route is the default route for trains
		default_prio -- optional, priority for multi-ars with default route
		default_conj = {...} -- optional, conditions (conjunction) that need to be fulfilled for this to be considered default route
	}
	
	In case a train matches the ARS rules of multiple routes, precedence is as follows:
	1. train matches rules without priority in one or more routes -> first matching route is unconditionally set
	2. train matches rules with priority in one or more routes -> all of the matching routes are set (multi-ars)
			in the order given by priority, first available route is set
	3. route is default=true, default_prio=nil and train matches default_conj (if present) -> first default route is set
	4. one or more routes are default=true, with default_prio set,and train matches default_conj (if present)
			-> all of the matching routes are set (multi-ars) in the order given by priority, first available route is set
	
	For editing, those tables are transformed into lines in a text area:
	{ln=...} -> LN ...
	{rc=...} -> RC ...
	{c=...}  -> #...
	{default=true} -> *
	n -> ! (e.g. ln=..., n=true -> !LN ...)
	prio -> <num> (e.g. ln=..., prio=1 -> 1 LN ...)
	
	conj -> goes on the next line, with an & prepended, e.g.:
		{ln="S1", conj={rc="Left"}} ->
		LN S1
		& RC Left
	
	Example combining everything:
	ars = {
		[1] = {
			ln = "S1"
			n = true
			prio = 4
			conj = {
				rc = "R4"
			}
		}
		default = true
		default_prio = 2
		default_conj = {
			rc = "R5"
			n = true
		}
	} ->
	4 !LN S1
	& RC R4
	2 *
	& !RC R5
	
]]

local il = advtrains.interlocking

local function parse_trainlen(tlstr)
	mins, maxs = string.match(tlstr, "^(%d*)%-(%d+)$")
	if mins and maxs then
		return {min=tonumber(mins), max=tonumber(maxs)}
	end
	return {min=tonumber(tlstr)}
	-- if it's not parseable at all it will return an empty table which means invalid
end
local function trainlen_to_str(tl)
	if tl.min and tl.max then
		return tl.min.."-"..tl.max
	elseif tl.min then
		return tl.min
	elseif tl.max then
		return "0-"..tl.max
	else
		return "?"
	end
end


local function conj_to_text(conj, txt)