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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
local S = atltrans
local ac = {nodes={}}
function ac.load(data)
if data then
ac.nodes=data.nodes
end
end
function ac.save()
return {nodes = ac.nodes}
end
function ac.after_place_node(pos, player)
local meta=minetest.get_meta(pos)
meta:set_string("formspec", ac.getform(pos, meta))
meta:set_string("infotext", S("Unconfigured LuaATC component"))
local ph=minetest.pos_to_string(pos)
--just get first available key!
for en,_ in pairs(atlatc.envs) do
ac.nodes[ph]={env=en}
return
end
end
function ac.getform(pos, meta_p)
local meta = meta_p or minetest.get_meta(pos)
local envs_asvalues={}
local ph=minetest.pos_to_string(pos)
local nodetbl = ac.nodes[ph]
local env, code, err = nil, "", ""
if nodetbl then
code=nodetbl.code or ""
err=nodetbl.err or ""
env=nodetbl.env or ""
end
local sel = 1
for n,_ in pairs(atlatc.envs) do
envs_asvalues[#envs_asvalues+1]=minetest.formspec_escape(n)
if n==env then
sel=#envs_asvalues
end
end
local form = "size["..atlatc.CODE_FORM_SIZE.."]"
.."style[code;font=mono]"
.."label[0,-0.1;"..S("LuaATC Environment").."]"
.."dropdown[0,0.3;3;env;"..table.concat(envs_asvalues, ",")..";"..sel.."]"
.."button[5,0.2;2,1;save;"..S("Save").."]"
.."button[7,0.2;3,1;cle;"..S("Clear Local Environment").."]"
.."textarea[0.3,1.5;"..atlatc.CODE_FORM_SIZE..";code;"..S("Code")..";"..minetest.formspec_escape(code).."]"
.."label["..atlatc.CODE_FORM_ERRLABELPOS..";"..err.."]"
return form
end
function ac.after_dig_node(pos, node, player)
advtrains.invalidate_all_paths(pos)
advtrains.ndb.clear(pos)
atlatc.interrupt.clear_ints_at_pos(pos)
if advtrains.lines and advtrains.lines.sched then
advtrains.lines.sched.discard_all(advtrains.encode_pos(pos))
end
local ph=minetest.pos_to_string(pos)
ac.nodes[ph]=nil
end
function ac.on_receive_fields(pos, formname, fields, player)
if not minetest.check_player_privs(player:get_player_name(), {atlatc=true}) then
minetest.chat_send_player(player:get_player_name(), S("You are not allowed to configure this LuaATC component without the @1 privilege.", "atlatc"))
return
end
local meta=minetest.get_meta(pos)
local ph=minetest.pos_to_string(pos)
local nodetbl = ac.nodes[ph] or {}
--if fields.quit then return end
if fields.env then
nodetbl.env=fields.env
end
if fields.code then
nodetbl.code=fields.code
end
if fields.save then
-- reset certain things
nodetbl.err=nil
if advtrains.lines and advtrains.lines.sched then
-- discard all schedules for this node
advtrains.lines.sched.discard_all(advtrains.encode_pos(pos))
end
end
if fields.cle then
nodetbl.data={}
end
ac.nodes[ph]=nodetbl
meta:set_string("formspec", ac.getform(pos, meta))
if nodetbl.env then
meta:set_string("infotext", S("LuaATC component assigned to environment '@1'", nodetbl.env))
else
meta:set_string("infotext", S("LuaATC component assigned to an invalid environment"))
end
end
function ac.run_in_env(pos, evtdata, customfct_p, ignore_no_code)
local ph=minetest.pos_to_string(pos)
local nodetbl = ac.nodes[ph]
if not nodetbl then
atwarn("LuaATC component at",ph,": Data not in memory! Please visit component and click 'Save'!")
return
end
local meta
if advtrains.is_node_loaded(pos) then
meta=minetest.get_meta(pos)
end
if not nodetbl.env or not atlatc.envs[nodetbl.env] then
atwarn("LuaATC component at",ph,": Not an existing environment: "..(nodetbl.env or "<nil>"))
return false
end
local env = atlatc.envs[nodetbl.env]
if not nodetbl.code or nodetbl.code=="" then
if not ignore_no_code then
env:log("warning", "LuaATC component at",ph,": No code to run! (insert -- to suppress warning)")
end
return false
end
local customfct=customfct_p or {}
-- add interrupt function
customfct.interrupt=function(t, imesg)
assertt(t, "number")
assert(t >= 0)
atlatc.interrupt.add(t, pos, {type="int", int=true, message=imesg, msg=imesg}) --Compatiblity "message" field.
end
customfct.interrupt_safe=function(t, imesg)
assertt(t, "number")
assert(t >= 0)
if atlatc.interrupt.has_at_pos(pos) then
return false
end
atlatc.interrupt.add(t, pos, {type="int", int=true, message=imesg, msg=imesg}) --Compatiblity "message" field.
return true
end
customfct.clear_interrupts=function()
atlatc.interrupt.clear_ints_at_pos(pos)
end
-- add digiline_send function, if digiline is loaded
if minetest.global_exists("digiline") then
customfct.digiline_send=function(channel, msg)
assertt(channel, "string")
if advtrains.is_node_loaded(pos) then
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
end
end
end
-- add lines scheduler if enabled
if advtrains.lines and advtrains.lines.sched then
customfct.schedule = function(rwtime, msg)
return advtrains.lines.sched.enqueue(rwtime, "atlatc_env", {pos=pos, msg=msg}, advtrains.encode_pos(pos), 1)
end
customfct.schedule_in = function(rwtime, msg)
return advtrains.lines.sched.enqueue_in(rwtime, "atlatc_env", {pos=pos, msg=msg}, advtrains.encode_pos(pos), 1)
end
end
local datain=nodetbl.data or {}
local succ, dataout = env:execute_code(datain, nodetbl.code, evtdata, customfct)
if succ then
atlatc.active.nodes[ph].data=atlatc.remove_invalid_data(dataout)
else
atlatc.active.nodes[ph].err=dataout
env:log("error", "LuaATC component at",ph,": LUA Error:",dataout)
if meta then
meta:set_string("infotext", S("LuaATC component with error: @1", dataout))
end
--TODO temporary
--if customfct.atc_id then
-- advtrains.drb_dump(customfct.atc_id)
-- error("Debug: LuaATC error hit!")
--end
end
if meta then
meta:set_string("formspec", ac.getform(pos, meta))
end
end
function ac.on_digiline_receive(pos, node, channel, msg)
atlatc.interrupt.add(0, pos, {type="digiline", digiline=true, channel = channel, msg = msg})
end
if advtrains.lines and advtrains.lines.sched then
advtrains.lines.sched.register_callback("atlatc_env", function(data)
-- This adds another interrupt to the atlatc queue... there might be a better way
atlatc.interrupt.add(0, data.pos, {type="schedule",schedule=true, msg=data.msg})
end)
end
ac.trackdef_advtrains_defs = {
on_train_enter = function(pos, train_id)
--do async. Event is fired in train steps
atlatc.interrupt.add(0, pos, {type="train", train=true, id=train_id})
end,
}
atlatc.active=ac
|