aboutsummaryrefslogtreecommitdiff
path: root/advtrains
diff options
context:
space:
mode:
authororwell96 <mono96.mml@gmail.com>2017-04-29 19:44:43 +0200
committerorwell96 <mono96.mml@gmail.com>2017-04-29 19:44:43 +0200
commit0c7144bcc49449eba9f6ab8f2c1d8efa72b0307a (patch)
treeeb66e11bc2a6fb1937d85e2006a7f20d39e40e0b /advtrains
parent331db7ba5f4e4b308c1f8efa93c2b40c5139766d (diff)
parentf42b01c74bdc7e91d3def03125a0e24e6a3bb0d4 (diff)
downloadadvtrains-0c7144bcc49449eba9f6ab8f2c1d8efa72b0307a.tar.gz
advtrains-0c7144bcc49449eba9f6ab8f2c1d8efa72b0307a.tar.bz2
advtrains-0c7144bcc49449eba9f6ab8f2c1d8efa72b0307a.zip
Merge nocrash branch into master and merging it with the unified functions so that restoring works how it should
Also fix minor bugs and an occasional crash with couples
Diffstat (limited to 'advtrains')
-rw-r--r--advtrains/advtrains/atc.lua80
-rw-r--r--advtrains/advtrains/couple.lua215
-rw-r--r--advtrains/advtrains/init.lua94
-rw-r--r--advtrains/advtrains/nocrash.lua0
-rw-r--r--advtrains/advtrains/nodedb.lua48
-rw-r--r--advtrains/advtrains/trackplacer.lua158
-rw-r--r--advtrains/advtrains/trainlogic.lua64
-rw-r--r--advtrains/advtrains/wagons.lua860
-rw-r--r--advtrains/advtrains_itrainmap/init.lua2
-rw-r--r--advtrains/advtrains_luaautomation/init.lua6
-rw-r--r--advtrains/advtrains_luaautomation/interrupt.lua32
11 files changed, 815 insertions, 744 deletions
diff --git a/advtrains/advtrains/atc.lua b/advtrains/advtrains/atc.lua
index 3925ffd..ed631a3 100644
--- a/advtrains/advtrains/atc.lua
+++ b/advtrains/advtrains/atc.lua
@@ -92,49 +92,53 @@ advtrains.register_tracks("default", {
return {
after_place_node=apn_func,
after_dig_node=function(pos)
- advtrains.invalidate_all_paths()
- advtrains.ndb.clear(pos)
- local pts=minetest.pos_to_string(pos)
- atc.controllers[pts]=nil
+ return advtrains.pcall(function()
+ advtrains.invalidate_all_paths()
+ advtrains.ndb.clear(pos)
+ local pts=minetest.pos_to_string(pos)
+ atc.controllers[pts]=nil
+ end)
end,
on_receive_fields = function(pos, formname, fields, player)
- if advtrains.is_protected(pos, player:get_player_name()) then
- minetest.record_protection_violation(pos, player:get_player_name())
- return
- end
- local meta=minetest.get_meta(pos)
- if meta then
- if not fields.save then
- --maybe only the dropdown changed
- if fields.mode then
- meta:set_string("mode", idxtrans[fields.mode])
- if fields.mode=="digiline" then
- meta:set_string("infotext", attrans("ATC controller, mode @1\nChannel: @2", fields.mode, meta:get_string("command")) )
- else
- meta:set_string("infotext", attrans("ATC controller, mode @1\nCommand: @2", fields.mode, meta:get_string("command")) )
- end
- meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
- end
+ return advtrains.pcall(function()
+ if advtrains.is_protected(pos, player:get_player_name()) then
+ minetest.record_protection_violation(pos, player:get_player_name())
return
end
- meta:set_string("mode", idxtrans[fields.mode])
- meta:set_string("command", fields.command)
- meta:set_string("command_on", fields.command_on)
- meta:set_string("channel", fields.channel)
- if fields.mode=="digiline" then
- meta:set_string("infotext", attrans("ATC controller, mode @1\nChannel: @2", fields.mode, meta:get_string("command")) )
- else
- meta:set_string("infotext", attrans("ATC controller, mode @1\nCommand: @2", fields.mode, meta:get_string("command")) )
- end
- meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
-
- local pts=minetest.pos_to_string(pos)
- local _, conn1=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
- atc.controllers[pts]={command=fields.command, arrowconn=conn1}
- if advtrains.detector.on_node[pts] then
- atc.send_command(pos)
+ local meta=minetest.get_meta(pos)
+ if meta then
+ if not fields.save then
+ --maybe only the dropdown changed
+ if fields.mode then
+ meta:set_string("mode", idxtrans[fields.mode])
+ if fields.mode=="digiline" then
+ meta:set_string("infotext", attrans("ATC controller, mode @1\nChannel: @2", fields.mode, meta:get_string("command")) )
+ else
+ meta:set_string("infotext", attrans("ATC controller, mode @1\nCommand: @2", fields.mode, meta:get_string("command")) )
+ end
+ meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
+ end
+ return
+ end
+ meta:set_string("mode", idxtrans[fields.mode])
+ meta:set_string("command", fields.command)
+ meta:set_string("command_on", fields.command_on)
+ meta:set_string("channel", fields.channel)
+ if fields.mode=="digiline" then
+ meta:set_string("infotext", attrans("ATC controller, mode @1\nChannel: @2", fields.mode, meta:get_string("command")) )
+ else
+ meta:set_string("infotext", attrans("ATC controller, mode @1\nCommand: @2", fields.mode, meta:get_string("command")) )
+ end
+ meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
+
+ local pts=minetest.pos_to_string(pos)
+ local _, conn1=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
+ atc.controllers[pts]={command=fields.command, arrowconn=conn1}
+ if advtrains.detector.on_node[pts] then
+ atc.send_command(pos)
+ end
end
- end
+ end)
end,
advtrains = {
on_train_enter = function(pos, train_id)
diff --git a/advtrains/advtrains/couple.lua b/advtrains/advtrains/couple.lua
index eb1bc72..ac4dfce 100644
--- a/advtrains/advtrains/couple.lua
+++ b/advtrains/advtrains/couple.lua
@@ -31,52 +31,56 @@ minetest.register_entity("advtrains:discouple", {
end,
get_staticdata=function() return "DISCOUPLE" end,
on_punch=function(self, player)
- --only if player owns at least one wagon next to this
- local own=player:get_player_name()
- if self.wagon.owner and self.wagon.owner==own and not self.wagon.lock_couples then
- local train=advtrains.trains[self.wagon.train_id]
- local nextwgn_id=train.trainparts[self.wagon.pos_in_trainparts-1]
- for aoi, le in pairs(minetest.luaentities) do
- if le and le.is_wagon then
- if le.unique_id==nextwgn_id then
- if le.owner and le.owner~=own then
- minetest.chat_send_player(own, attrans("You need to own at least one neighboring wagon to destroy this couple."))
- return
+ return advtrains.pcall(function()
+ --only if player owns at least one wagon next to this
+ local own=player:get_player_name()
+ if self.wagon.owner and self.wagon.owner==own and not self.wagon.lock_couples then
+ local train=advtrains.trains[self.wagon.train_id]
+ local nextwgn_id=train.trainparts[self.wagon.pos_in_trainparts-1]
+ for aoi, le in pairs(minetest.luaentities) do
+ if le and le.is_wagon then
+ if le.unique_id==nextwgn_id then
+ if le.owner and le.owner~=own then
+ minetest.chat_send_player(own, attrans("You need to own at least one neighboring wagon to destroy this couple."))
+ return
+ end
end
end
end
+ atprint("Discouple punched. Splitting train", self.wagon.train_id)
+ advtrains.split_train_at_wagon(self.wagon)--found in trainlogic.lua
+ self.object:remove()
+ elseif self.wagon.lock_couples then
+ minetest.chat_send_player(own, "Couples of one of the wagons are locked, can't discouple!")
+ else
+ minetest.chat_send_player(own, attrans("You need to own at least one neighboring wagon to destroy this couple."))
end
- atprint("Discouple punched. Splitting train", self.wagon.train_id)
- advtrains.split_train_at_wagon(self.wagon)--found in trainlogic.lua
- self.object:remove()
- elseif self.wagon.lock_couples then
- minetest.chat_send_player(own, "Couples of one of the wagons are locked, can't discouple!")
- else
- minetest.chat_send_player(own, attrans("You need to own at least one neighboring wagon to destroy this couple."))
- end
+ end)
end,
on_step=function(self, dtime)
- local t=os.clock()
- if not self.wagon then
- self.object:remove()
- atprint("Discouple: no wagon, destroying")
- return
- end
- --getyaw seems to be a reliable method to check if an object is loaded...if it returns nil, it is not.
- if not self.wagon.object:getyaw() then
- atprint("Discouple: wagon no longer loaded, destroying")
- self.object:remove()
- return
- end
- local velocityvec=self.wagon.object:getvelocity()
- self.updatepct_timer=(self.updatepct_timer or 0)-dtime
- if not self.old_velocity_vector or not vector.equals(velocityvec, self.old_velocity_vector) or self.updatepct_timer<=0 then--only send update packet if something changed
- local flipsign=self.wagon.wagon_flipped and -1 or 1
- self.object:setpos(vector.add(self.wagon.object:getpos(), {y=0, x=-math.sin(self.wagon.object:getyaw())*self.wagon.wagon_span*flipsign, z=math.cos(self.wagon.object:getyaw())*self.wagon.wagon_span*flipsign}))
- self.object:setvelocity(velocityvec)
- self.updatepct_timer=2
- end
- atprintbm("discouple_step", t)
+ return advtrains.pcall(function()
+ local t=os.clock()
+ if not self.wagon then
+ self.object:remove()
+ atprint("Discouple: no wagon, destroying")
+ return
+ end
+ --getyaw seems to be a reliable method to check if an object is loaded...if it returns nil, it is not.
+ if not self.wagon.object:getyaw() then
+ atprint("Discouple: wagon no longer loaded, destroying")
+ self.object:remove()
+ return
+ end
+ local velocityvec=self.wagon.object:getvelocity()
+ self.updatepct_timer=(self.updatepct_timer or 0)-dtime
+ if not self.old_velocity_vector or not vector.equals(velocityvec, self.old_velocity_vector) or self.updatepct_timer<=0 then--only send update packet if something changed
+ local flipsign=self.wagon.wagon_flipped and -1 or 1
+ self.object:setpos(vector.add(self.wagon.object:getpos(), {y=0, x=-math.sin(self.wagon.object:getyaw())*self.wagon.wagon_span*flipsign, z=math.cos(self.wagon.object:getyaw())*self.wagon.wagon_span*flipsign}))
+ self.object:setvelocity(velocityvec)
+ self.updatepct_timer=2
+ end
+ atprintbm("discouple_step", t)
+ end)
end,
})
@@ -98,74 +102,79 @@ minetest.register_entity("advtrains:couple", {
initial_sprite_basepos = {x=0, y=0},
is_couple=true,
- on_activate=function(self, staticdata)
- if staticdata=="COUPLE" then
- --couple entities have no right to exist further...
- atprint("Couple loaded from staticdata, destroying")
- self.object:remove()
- return
- end
+ on_activate=function(self, staticdata)
+ return advtrains.pcall(function()
+ if staticdata=="COUPLE" then
+ --couple entities have no right to exist further...
+ atprint("Couple loaded from staticdata, destroying")
+ self.object:remove()
+ return
+ end
+ end)
end,
get_staticdata=function(self) return "COUPLE" end,
on_rightclick=function(self, clicker)
- if not self.train_id_1 or not self.train_id_2 then return end
-
- local id1, id2=self.train_id_1, self.train_id_2
-
- if self.train1_is_backpos and not self.train2_is_backpos then
- advtrains.do_connect_trains(id1, id2, clicker)
- --case 2 (second train is front)
- elseif self.train2_is_backpos and not self.train1_is_backpos then
- advtrains.do_connect_trains(id2, id1, clicker)
- --case 3
- elseif self.train1_is_backpos and self.train2_is_backpos then
- advtrains.invert_train(id2)
- advtrains.do_connect_trains(id1, id2, clicker)
- --case 4
- elseif not self.train1_is_backpos and not self.train2_is_backpos then
- advtrains.invert_train(id1)
- advtrains.do_connect_trains(id1, id2, clicker)
- end
- atprint("Coupled trains", id1, id2)
- self.object:remove()
+ return advtrains.pcall(function()
+ if not self.train_id_1 or not self.train_id_2 then return end
+
+ local id1, id2=self.train_id_1, self.train_id_2
+ if self.train1_is_backpos and not self.train2_is_backpos then
+ advtrains.do_connect_trains(id1, id2, clicker)
+ --case 2 (second train is front)
+ elseif self.train2_is_backpos and not self.train1_is_backpos then
+ advtrains.do_connect_trains(id2, id1, clicker)
+ --case 3
+ elseif self.train1_is_backpos and self.train2_is_backpos then
+ advtrains.invert_train(id2)
+ advtrains.do_connect_trains(id1, id2, clicker)
+ --case 4
+ elseif not self.train1_is_backpos and not self.train2_is_backpos then
+ advtrains.invert_train(id1)
+ advtrains.do_connect_trains(id1, id2, clicker)
+ end
+ atprint("Coupled trains", id1, id2)
+ self.object:remove()
+ end)
end,
on_step=function(self, dtime)
- local t=os.clock()
- if not self.train_id_1 or not self.train_id_2 then atprint("Couple: train ids not set!") self.object:remove() return end
- local train1=advtrains.trains[self.train_id_1]
- local train2=advtrains.trains[self.train_id_2]
- if not train1 or not train2 then
- atprint("Couple: trains missing, destroying")
- self.object:remove()
- return
- end
- if not train1.path or not train2.path or not train1.index or not train2.index or not train1.end_index or not train2.end_index then
- atprint("Couple: paths or end_index missing. Might happen when paths got cleared")
- return
- end
-
- local tp1
- if not self.train1_is_backpos then
- tp1=advtrains.get_real_index_position(train1.path, train1.index)
- else
- tp1=advtrains.get_real_index_position(train1.path, train1.end_index)
- end
- local tp2
- if not self.train2_is_backpos then
- tp2=advtrains.get_real_index_position(train2.path, train2.index)
- else
- tp2=advtrains.get_real_index_position(train2.path, train2.end_index)
- end
- if not tp1 or not tp2 or not (vector.distance(tp1,tp2)<couple_max_dist) then
- atprint("Couple: train end positions too distanced, destroying")
- self.object:remove()
- return
- else
- local pos_median=advtrains.pos_median(tp1, tp2)
- if not vector.equals(pos_median, self.object:getpos()) then
- self.object:setpos(pos_median)
+ return advtrains.pcall(function()
+ local t=os.clock()
+ if not self.train_id_1 or not self.train_id_2 then atprint("Couple: train ids not set!") self.object:remove() return end
+ local train1=advtrains.trains[self.train_id_1]
+ local train2=advtrains.trains[self.train_id_2]
+ if not train1 or not train2 then
+ atprint("Couple: trains missing, destroying")
+ self.object:remove()
+ return
end
- end
- atprintbm("couple step", t)
+ if not train1.path or not train2.path or not train1.index or not train2.index or not train1.end_index or not train2.end_index then
+ atprint("Couple: paths or end_index missing. Might happen when paths got cleared")
+ return
+ end
+
+ local tp1
+ if not self.train1_is_backpos then
+ tp1=advtrains.get_real_index_position(train1.path, train1.index)
+ else
+ tp1=advtrains.get_real_index_position(train1.path, train1.end_index)
+ end
+ local tp2
+ if not self.train2_is_backpos then
+ tp2=advtrains.get_real_index_position(train2.path, train2.index)
+ else
+ tp2=advtrains.get_real_index_position(train2.path, train2.end_index)
+ end
+ if not tp1 or not tp2 or not (vector.distance(tp1,tp2)<couple_max_dist) then
+ atprint("Couple: train end positions too distanced, destroying")
+ self.object:remove()
+ return
+ else
+ local pos_median=advtrains.pos_median(tp1, tp2)
+ if not vector.equals(pos_median, self.object:getpos()) then
+ self.object:setpos(pos_median)
+ end
+ end
+ atprintbm("couple step", t)
+ end)
end,
})
diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua
index 4098729..022fcee 100644
--- a/advtrains/advtrains/init.lua
+++ b/advtrains/advtrains/init.lua
@@ -9,6 +9,29 @@ end
advtrains = {trains={}, wagon_save={}, player_to_train_mapping={}}
+--pcall
+local no_action=false
+function advtrains.pcall(fun)
+ if no_action then return end
+
+ local succ, err, return1, return2, return3, return4=pcall(fun)
+ if not succ then
+ atwarn("Lua Error occured: ", err)
+ atwarn("Restoring saved state in 1 second...")
+ no_action=true
+ --read last save state and continue, as if server was restarted
+ for aoi, le in pairs(minetest.luaentities) do
+ if le.is_wagon then
+ le.object:remove()
+ end
+ end
+ minetest.after(1, advtrains.load)
+ else
+ return err, return1, return2, return3, return4
+ end
+end
+
+
advtrains.modpath = minetest.get_modpath("advtrains")
function advtrains.print_concat_table(a)
@@ -94,6 +117,7 @@ dofile(advtrains.modpath.."/craft_items.lua")
--load/save
advtrains.fpath=minetest.get_worldpath().."/advtrains"
+
function advtrains.avt_load()
local file, err = io.open(advtrains.fpath, "r")
if not file then
@@ -197,44 +221,47 @@ end
--## MAIN LOOP ##--
--Calls all subsequent main tasks of both advtrains and atlatc
-local init_load
+local init_load=false
local save_interval=20
local save_timer=save_interval
minetest.register_globalstep(function(dtime_mt)
- --call load once. see advtrains.load() comment
- if not init_load then
- advtrains.load()
- end
- --limit dtime: if trains move too far in one step, automation may cause stuck and wrongly braking trains
- local dtime=dtime_mt
- if dtime>0.2 then
- atprint("Limiting dtime to 0.2!")
- dtime=0.2
- end
-
- advtrains.mainloop_trainlogic(dtime)
- if advtrains_itm_mainloop then
- advtrains_itm_mainloop(dtime)
- end
- if atlatc then
- atlatc.mainloop_stepcode(dtime)
- atlatc.interrupt.mainloop(dtime)
- end
-
-
- --trigger a save when necessary
- save_timer=save_timer-dtime
- if save_timer<=0 then
- local t=os.clock()
- --save
- advtrains.save()
- save_timer=save_interval
- atprintbm("saving", t)
- end
-
+ return advtrains.pcall(function()
+ --call load once. see advtrains.load() comment
+ if not init_load then
+ advtrains.load()
+ end
+ --limit dtime: if trains move too far in one step, automation may cause stuck and wrongly braking trains
+ local dtime=dtime_mt
+ if dtime>0.2 then
+ atprint("Limiting dtime to 0.2!")
+ dtime=0.2
+ end
+
+ advtrains.mainloop_trainlogic(dtime)
+ if advtrains_itm_mainloop then
+ advtrains_itm_mainloop(dtime)
+ end
+ if atlatc then
+ atlatc.mainloop_stepcode(dtime)
+ atlatc.interrupt.mainloop(dtime)
+ end
+
+
+ --trigger a save when necessary
+ save_timer=save_timer-dtime
+ if save_timer<=0 then
+ local t=os.clock()
+ --save
+ advtrains.save()
+ save_timer=save_interval
+ atprintbm("saving", t)
+ end
+ end)
end)
+--if something goes wrong in these functions, there is no help. no pcall here.
+
--## MAIN LOAD ROUTINE ##
-- Causes the loading of everything
-- first time called in main loop (after the init phase) because luaautomation has to initialize first.
@@ -247,6 +274,8 @@ function advtrains.load()
advtrains_itm_init()
end
init_load=true
+ no_action=false
+ atprint("[load_all]Loaded advtrains save files")
end
--## MAIN SAVE ROUTINE ##
@@ -261,5 +290,6 @@ function advtrains.save()
if atlatc then
atlatc.save()
end
+ atprint("[save_all]Saved advtrains save files")
end
minetest.register_on_shutdown(advtrains.save)
diff --git a/advtrains/advtrains/nocrash.lua b/advtrains/advtrains/nocrash.lua
deleted file mode 100644
index e69de29..0000000
--- a/advtrains/advtrains/nocrash.lua
+++ /dev/null
diff --git a/advtrains/advtrains/nodedb.lua b/advtrains/advtrains/nodedb.lua
index ddd1a67..55adea8 100644
--- a/advtrains/advtrains/nodedb.lua
+++ b/advtrains/advtrains/nodedb.lua
@@ -203,37 +203,41 @@ minetest.register_abm({
nodenames = {"group:save_in_nodedb"},
run_at_every_load = true,
action = function(pos, node)
- local cid=ndbget(pos.x, pos.y, pos.z)
- if cid then
- --if in database, detect changes and apply.
- local nodeid = ndb_nodeids[u14b(cid)]
- local param2 = l2b(cid)
- if not nodeid then
- --something went wrong
- atprint("nodedb: lbm nid not found", pos, "with nid", u14b(cid), "param2", param2, "cid is", cid)
- ndb.update(pos, node)
- else
- if (nodeid~=node.name or param2~=node.param2) then
- atprint("nodedb: lbm replaced", pos, "with nodeid", nodeid, "param2", param2, "cid is", cid)
- minetest.swap_node(pos, {name=nodeid, param2 = param2})
- local ndef=minetest.registered_nodes[nodeid]
- if ndef and ndef.on_updated_from_nodedb then
- ndef.on_updated_from_nodedb(pos, node)
+ return advtrains.pcall(function()
+ local cid=ndbget(pos.x, pos.y, pos.z)
+ if cid then
+ --if in database, detect changes and apply.
+ local nodeid = ndb_nodeids[u14b(cid)]
+ local param2 = l2b(cid)
+ if not nodeid then
+ --something went wrong
+ atprint("nodedb: lbm nid not found", pos, "with nid", u14b(cid), "param2", param2, "cid is", cid)
+ ndb.update(pos, node)
+ else
+ if (nodeid~=node.name or param2~=node.param2) then
+ atprint("nodedb: lbm replaced", pos, "with nodeid", nodeid, "param2", param2, "cid is", cid)
+ minetest.swap_node(pos, {name=nodeid, param2 = param2})
+ local ndef=minetest.registered_nodes[nodeid]
+ if ndef and ndef.on_updated_from_nodedb then
+ ndef.on_updated_from_nodedb(pos, node)
+ end
end
end
+ else
+ --if not in database, take it.
+ atprint("nodedb: ", pos, "not in database")
+ ndb.update(pos, node)
end
- else
- --if not in database, take it.
- atprint("nodedb: ", pos, "not in database")
- ndb.update(pos, node)
- end
+ end)
end,
interval=10,
chance=1,
})
minetest.register_on_dignode(function(pos, oldnode, digger)
- ndb.clear(pos)
+ return advtrains.pcall(function()
+ ndb.clear(pos)
+ end)
end)
function ndb.get_nodes()
diff --git a/advtrains/advtrains/trackplacer.lua b/advtrains/advtrains/trackplacer.lua
index e039800..105b77e 100644
--- a/advtrains/advtrains/trackplacer.lua
+++ b/advtrains/advtrains/trackplacer.lua
@@ -187,26 +187,28 @@ function tp.register_track_placer(nnprefix, imgprefix, dispname)
wield_image = imgprefix.."_placer.png",
groups={},
on_place = function(itemstack, placer, pointed_thing)
- local name = placer:get_player_name()
- if not name then
- return itemstack
- end
- if pointed_thing.type=="node" then
- local pos=pointed_thing.above
- local upos=vector.subtract(pointed_thing.above, {x=0, y=1, z=0})
- if advtrains.is_protected(pos,name) then
- minetest.record_protection_violation(pos, name)
- return itemstack
+ return advtrains.pcall(function()
+ local name = placer:get_player_name()
+ if not name then
+ return itemstack
end
- if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to
- and minetest.registered_nodes[minetest.get_node(upos).name] and minetest.registered_nodes[minetest.get_node(upos).name].walkable then
- tp.placetrack(pos, nnprefix, placer, itemstack, pointed_thing)
- if not minetest.setting_getbool("creative_mode") then
- itemstack:take_item()
+ if pointed_thing.type=="node" then
+ local pos=pointed_thing.above
+ local upos=vector.subtract(pointed_thing.above, {x=0, y=1, z=0})
+ if advtrains.is_protected(pos,name) then
+ minetest.record_protection_violation(pos, name)
+ return itemstack
+ end
+ if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to
+ and minetest.registered_nodes[minetest.get_node(upos).name] and minetest.registered_nodes[minetest.get_node(upos).name].walkable then
+ tp.placetrack(pos, nnprefix, placer, itemstack, pointed_thing)
+ if not minetest.setting_getbool("creative_mode") then
+ itemstack:take_item()
+ end
end
end
- end
- return itemstack
+ return itemstack
+ end)
end,
})
end
@@ -220,78 +222,82 @@ minetest.register_craftitem("advtrains:trackworker",{
wield_image = "advtrains_trackworker.png",
stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
- local name = placer:get_player_name()
- if not name then
- return
- end
- if pointed_thing.type=="node" then
- local pos=pointed_thing.under
- if advtrains.is_protected(pos, name) then
- minetest.record_protection_violation(pos, name)
+ return advtrains.pcall(function()
+ local name = placer:get_player_name()
+ if not name then
return
end
- local node=minetest.get_node(pos)
+ if pointed_thing.type=="node" then
+ local pos=pointed_thing.under
+ if advtrains.is_protected(pos, name) then
+ minetest.record_protection_violation(pos, name)
+ return
+ end
+ local node=minetest.get_node(pos)
- --if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
- if advtrains.get_train_at_pos(pos) then return end
+ --if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
+ if advtrains.get_train_at_pos(pos) then return end
- local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
- --atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
- if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twrotate[suffix] then
- nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
- rotation = ""
+ local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
+ --atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twrotate[suffix] then
- minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
- return
+ nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
+ rotation = ""
+ if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twrotate[suffix] then
+ minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
+ return
+ end
end
- end
- local modext=tp.tracks[nnprefix].twrotate[suffix]
+ local modext=tp.tracks[nnprefix].twrotate[suffix]
- if rotation==modext[#modext] then --increase param2
- advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[1], param2=(node.param2+1)%4})
- return
- else
- local modpos
- for k,v in pairs(modext) do if v==rotation then modpos=k end end
- if not modpos then
- minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
+ if rotation==modext[#modext] then --increase param2
+ advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[1], param2=(node.param2+1)%4})
return
+ else
+ local modpos
+ for k,v in pairs(modext) do if v==rotation then modpos=k end end
+ if not modpos then
+ minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
+ return
+ end
+ advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[modpos+1], param2=node.param2})
end
- advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[modpos+1], param2=node.param2})
end
- end
+ end)
end,
on_use=function(itemstack, user, pointed_thing)
- local name = user:get_player_name()
- if not name then
- return
- end
- if pointed_thing.type=="node" then
- local pos=pointed_thing.under
- local node=minetest.get_node(pos)
- if advtrains.is_protected(pos, name) then
- minetest.record_protection_violation(pos, name)
- return
+ return advtrains.pcall(function()
+ local name = user:get_player_name()
+ if not name then
+ return
end
-
- --if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
- if advtrains.get_train_at_pos(pos) then return end
- local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
- --atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
- if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
- nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
- rotation = ""
- if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
- minetest.chat_send_player(user:get_player_name(), attrans("This node can't be changed using the trackworker!"))
- return
- end
- end
- local nextsuffix=tp.tracks[nnprefix].twcycle[suffix]
- advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..nextsuffix..rotation, param2=node.param2})
-
- else
- atprint(name, dump(tp.tracks))
- end
+ if pointed_thing.type=="node" then
+ local pos=pointed_thing.under
+ local node=minetest.get_node(pos)
+ if advtrains.is_protected(pos, name) then
+ minetest.record_protection_violation(pos, name)
+ return
+ end
+
+ --if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
+ if advtrains.get_train_at_pos(pos) then return end
+ local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
+ --atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
+ if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
+ nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
+ rotation = ""
+ if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
+ minetest.chat_send_player(user:get_player_name(), attrans("This node can't be changed using the trackworker!"))
+ return
+ end
+ end
+ local nextsuffix=tp.tracks[nnprefix].twcycle[suffix]
+ advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..nextsuffix..rotation, param2=node.param2})
+
+ else
+ atprint(name, dump(tp.tracks))
+ end
+ end)
end,
})
diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua
index 98a0e2b..7dad80c 100644
--- a/advtrains/advtrains/trainlogic.lua
+++ b/advtrains/advtrains/trainlogic.lua
@@ -37,8 +37,7 @@ advtrains.train_roll_force=0.5--per second, not divided by number of wagons, acc
advtrains.train_emerg_force=10--for emergency brakes(when going off track)
-advtrains.mainloop_trainlogic(function(dtime)
-
+advtrains.mainloop_trainlogic=function(dtime)
--build a table of all players indexed by pts. used by damage and door system.
advtrains.playersbypts={}
for _, player in pairs(minetest.get_connected_players()) do
@@ -67,39 +66,43 @@ advtrains.mainloop_trainlogic(function(dtime)
end
minetest.register_on_joinplayer(function(player)
- local pname=player:get_player_name()
- local id=advtrains.player_to_train_mapping[pname]
- if id then
- local train=advtrains.trains[id]
- if not train then advtrains.player_to_train_mapping[pname]=nil return end
- --set the player to the train position.
- --minetest will emerge the area and load the objects, which then will call reattach_all().
- --because player is in mapping, it will not be subject to dying.
- player:setpos(train.last_pos_prev)
- --independent of this, cause all wagons of the train which are loaded to reattach their players
- --needed because already loaded wagons won't call reattach_all()
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
- wagon:reattach_all()
+ return advtrains.pcall(function()
+ local pname=player:get_player_name()
+ local id=advtrains.player_to_train_mapping[pname]
+ if id then
+ local train=advtrains.trains[id]
+ if not train then advtrains.player_to_train_mapping[pname]=nil return end
+ --set the player to the train position.
+ --minetest will emerge the area and load the objects, which then will call reattach_all().
+ --because player is in mapping, it will not be subject to dying.
+ player:setpos(train.last_pos_prev)
+ --independent of this, cause all wagons of the train which are loaded to reattach their players
+ --needed because already loaded wagons won't call reattach_all()
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
+ wagon:reattach_all()
+ end
end
end
- end
+ end)
end)
minetest.register_on_dieplayer(function(player)
- local pname=player:get_player_name()
- local id=advtrains.player_to_train_mapping[pname]
- if id then
- local train=advtrains.trains[id]
- if not train then advtrains.player_to_train_mapping[pname]=nil return end
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
- --when player dies, detach him from the train
- --call get_off_plr on every wagon since we don't know which one he's on.
- wagon:get_off_plr(pname)
+ return advtrains.pcall(function()
+ local pname=player:get_player_name()
+ local id=advtrains.player_to_train_mapping[pname]
+ if id then
+ local train=advtrains.trains[id]
+ if not train then advtrains.player_to_train_mapping[pname]=nil return end
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
+ --when player dies, detach him from the train
+ --call get_off_plr on every wagon since we don't know which one he's on.
+ wagon:get_off_plr(pname)
+ end
end
end
- end
+ end)
end)
--[[
train step structure:
@@ -797,6 +800,10 @@ end
function advtrains.do_connect_trains(first_id, second_id, player)
local first, second=advtrains.trains[first_id], advtrains.trains[second_id]
+ if not first or not second or not first.index or not second.index or not first.end_index or not second.end_index then
+ return false
+ end
+
if first.couple_lock_back or second.couple_lock_front then
-- trains are ordered correctly!
if player then
@@ -817,6 +824,7 @@ function advtrains.do_connect_trains(first_id, second_id, player)
advtrains.update_trainpart_properties(first_id)
advtrains.trains[first_id].velocity=new_velocity
advtrains.trains[first_id].tarvelocity=0
+ return true
end
function advtrains.invert_train(train_id)
diff --git a/advtrains/advtrains/wagons.lua b/advtrains/advtrains/wagons.lua
index 15a0ec7..3325879 100644
--- a/advtrains/advtrains/wagons.lua
+++ b/advtrains/advtrains/wagons.lua
@@ -50,19 +50,21 @@ function wagon:on_activate(sd_uid, dtime_s)
end
function wagon:get_staticdata()
- if not self:ensure_init() then return end
- atprint("[wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: saving to wagon_save")
- --serialize inventory, if it has one
- if self.has_inventory then
- local inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..self.unique_id})
- self.ser_inv=advtrains.serialize_inventory(inv)
- end
- --save to table before being unloaded
- advtrains.wagon_save[self.unique_id]=advtrains.merge_tables(self)
- advtrains.wagon_save[self.unique_id].entity_name=self.name
- advtrains.wagon_save[self.unique_id].name=nil
- advtrains.wagon_save[self.unique_id].object=nil
- return self.unique_id
+ return advtrains.pcall(function()
+ if not self:ensure_init() then return end
+ atprint("[wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: saving to wagon_save")
+ --serialize inventory, if it has one
+ if self.has_inventory then
+ local inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..self.unique_id})
+ self.ser_inv=advtrains.serialize_inventory(inv)
+ end
+ --save to table before being unloaded
+ advtrains.wagon_save[self.unique_id]=advtrains.merge_tables(self)
+ advtrains.wagon_save[self.unique_id].entity_name=self.name
+ advtrains.wagon_save[self.unique_id].name=nil
+ advtrains.wagon_save[self.unique_id].object=nil
+ return self.unique_id
+ end)
end
--returns: uid of wagon
function wagon:init_new_instance(train_id, properties)
@@ -147,36 +149,38 @@ end
-- Remove the wagon
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
- if not self:ensure_init() then return end
- if not puncher or not puncher:is_player() then
- return
- end
- if self.owner and puncher:get_player_name()~=self.owner and (not minetest.check_player_privs(puncher, {train_remove = true })) then
- minetest.chat_send_player(puncher:get_player_name(), attrans("This wagon is owned by @1, you can't destroy it.", self.owner));
- return
- end
-
- if minetest.setting_getbool("creative_mode") then
- if not self:destroy() then return end
-
- local inv = puncher:get_inventory()
- if not inv:contains_item("main", self.name) then
- inv:add_item("main", self.name)
- end
- else
- local pc=puncher:get_player_control()
- if not pc.sneak then
- minetest.chat_send_player(puncher:get_player_name(), attrans("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
+ return advtrains.pcall(function()
+ if not self:ensure_init() then return end
+ if not puncher or not puncher:is_player() then
return
end
+ if self.owner and puncher:get_player_name()~=self.owner and (not minetest.check_player_privs(puncher, {train_remove = true })) then
+ minetest.chat_send_player(puncher:get_player_name(), attrans("This wagon is owned by @1, you can't destroy it.", self.owner));
+ return
+ end
+
+ if minetest.setting_getbool("creative_mode") then
+ if not self:destroy() then return end
+
+ local inv = puncher:get_inventory()
+ if not inv:contains_item("main", self.name) then
+ inv:add_item("main", self.name)
+ end
+ else
+ local pc=puncher:get_player_control()
+ if not pc.sneak then
+ minetest.chat_send_player(puncher:get_player_name(), attrans("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
+ return
+ end
- if not self:destroy() then return end
+ if not self:destroy() then return end
- local inv = puncher:get_inventory()
- for _,item in ipairs(self.drops or {self.name}) do
- inv:add_item("main", item)
+ local inv = puncher:get_inventory()
+ for _,item in ipairs(self.drops or {self.name}) do
+ inv:add_item("main", item)
+ end
end
- end
+ end)
end
function wagon:destroy()
--some rules:
@@ -211,260 +215,262 @@ end
function wagon:on_step(dtime)
- if not self:ensure_init() then return end
-
- local t=os.clock()
- local pos = self.object:getpos()
-
- if not pos then
- atprint("["..self.unique_id.."][fatal] missing position (object:getpos() returned nil)")
- return
- end
+ return advtrains.pcall(function()
+ if not self:ensure_init() then return end
+
+ local t=os.clock()
+ local pos = self.object:getpos()
+
+ if not pos then
+ atprint("["..self.unique_id.."][fatal] missing position (object:getpos() returned nil)")
+ return
+ end
- self.entity_name=self.name
-
- --is my train still here
- if not self.train_id or not self:train() then
- atprint("[wagon "..self.unique_id.."] missing train_id, destroying")
- self.object:remove()
- return
- end
- if not self.seatp then
- self.seatp={}
- end
- if not self.seatpc then
- self.seatpc={}
- end
-
- --Legacy: remove infotext since it does not work this way anyways
- self.infotext=nil
+ self.entity_name=self.name
+
+ --is my train still here
+ if not self.train_id or not self:train() then
+ atprint("[wagon "..self.unique_id.."] missing train_id, destroying")
+ self.object:remove()
+ return
+ end
+ if not self.seatp then
+ self.seatp={}
+ end
+ if not self.seatpc then
+ self.seatpc={}
+ end
+
+ --Legacy: remove infotext since it does not work this way anyways
+ self.infotext=nil
- --custom on_step function
- if self.custom_on_step then
- self:custom_on_step(self, dtime)
- end
+ --custom on_step function
+ if self.custom_on_step then
+ self:custom_on_step(self, dtime)
+ end
- --driver control
- for seatno, seat in ipairs(self.seats) do
- local driver=self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
- local has_driverstand=seat.driving_ctrl_access and self.seatp[seatno] and minetest.check_player_privs(self.seatp[seatno], {train_operator=true})
- if has_driverstand and driver then
- advtrains.update_driver_hud(driver:get_player_name(), self:train(), self.wagon_flipped)
- elseif driver then
- --only show the inside text
- local inside=self:train().text_inside or ""
- advtrains.set_trainhud(driver:get_player_name(), inside)
- end
- if driver and driver:get_player_control_bits()~=self.seatpc[seatno] then
- local pc=driver:get_player_control()
- self.seatpc[seatno]=driver:get_player_control_bits()
-
- if has_driverstand then
- --regular driver stand controls
- advtrains.on_control_change(pc, self:train(), self.wagon_flipped)
- else
- -- If on a passenger seat and doors are open, get off when W or D pressed.
- local pass = self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
- if pass and self:train().door_open~=0 then
- local pc=pass:get_player_control()
- if pc.up or pc.down then
- self:get_off(seatno)
- end
- end
- end
- if pc.aux1 and pc.sneak then
- self:get_off(seatno)
+ --driver control
+ for seatno, seat in ipairs(self.seats) do
+ local driver=self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
+ local has_driverstand=seat.driving_ctrl_access and self.seatp[seatno] and minetest.check_player_privs(self.seatp[seatno], {train_operator=true})
+ if has_driverstand and driver then
+ advtrains.update_driver_hud(driver:get_player_name(), self:train(), self.wagon_flipped)
+ elseif driver then
+ --only show the inside text
+ local inside=self:train().text_inside or ""
+ advtrains.set_trainhud(driver:get_player_name(), inside)
end
- end
- end
-
- --check infotext
- local outside=self:train().text_outside or ""
- if self.object:get_properties().infotext~=outside then
- self.object:set_properties({infotext=outside})
- end
-
- local gp=self:train()
- local fct=self.wagon_flipped and -1 or 1
- --door animation
- if self.doors then
- if (self.door_anim_timer or 0)<=0 then
- local dstate = (gp.door_open or 0) * fct
- if dstate ~= self.door_state then
- local at
- --meaning of the train.door_open field:
- -- -1: left doors (rel. to train orientation)
- -- 0: closed
- -- 1: right doors
- --this code produces the following behavior:
- -- if changed from 0 to +-1, play open anim. if changed from +-1 to 0, play close.
- -- if changed from +-1 to -+1, first close and set 0, then it will detect state change again and run open.
- if self.door_state == 0 then
- at=self.doors.open[dstate]
- self.object:set_animation(at.frames, at.speed or 15, at.blend or 0, false)
- self.door_state = dstate
+ if driver and driver:get_player_control_bits()~=self.seatpc[seatno] then
+ local pc=driver:get_player_control()
+ self.seatpc[seatno]=driver:get_player_control_bits()
+
+ if has_driverstand then
+ --regular driver stand controls
+ advtrains.on_control_change(pc, self:train(), self.wagon_flipped)
else
- at=self.doors.close[self.door_state or 1]--in case it has not been set yet
- self.object:set_animation(at.frames, at.speed or 15, at.blend or 0, false)
- self.door_state = 0
+ -- If on a passenger seat and doors are open, get off when W or D pressed.
+ local pass = self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
+ if pass and self:train().door_open~=0 then
+ local pc=pass:get_player_control()
+ if pc.up or pc.down then
+ self:get_off(seatno)
+ end
+ end
+ end
+ if pc.aux1 and pc.sneak then
+ self:get_off(seatno)
end
- self.door_anim_timer = at.time
end
- else
- self.door_anim_timer = (self.door_anim_timer or 0) - dtime
end
- end
-
- --DisCouple
- if self.pos_in_trainparts and self.pos_in_trainparts>1 then
- if gp.velocity==0 and not self.lock_couples then
- if not self.discouple or not self.discouple.object:getyaw() then
- local object=minetest.add_entity(pos, "advtrains:discouple")
- if object then
- local le=object:get_luaentity()
- le.wagon=self
- --box is hidden when attached, so unuseful.
- --object:set_attach(self.object, "", {x=0, y=0, z=self.wagon_span*10}, {x=0, y=0, z=0})
- self.discouple=le
- else
- atprint("Couldn't spawn DisCouple")
+
+ --check infotext
+ local outside=self:train().text_outside or ""
+ if self.object:get_properties().infotext~=outside then
+ self.object:set_properties({infotext=outside})
+ end
+
+ local gp=self:train()
+ local fct=self.wagon_flipped and -1 or 1
+ --door animation
+ if self.doors then
+ if (self.door_anim_timer or 0)<=0 then
+ local dstate = (gp.door_open or 0) * fct
+ if dstate ~= self.door_state then
+ local at
+ --meaning of the train.door_open field:
+ -- -1: left doors (rel. to train orientation)
+ -- 0: closed
+ -- 1: right doors
+ --this code produces the following behavior:
+ -- if changed from 0 to +-1, play open anim. if changed from +-1 to 0, play close.
+ -- if changed from +-1 to -+1, first close and set 0, then it will detect state change again and run open.
+ if self.door_state == 0 then
+ at=self.doors.open[dstate]
+ self.object:set_animation(at.frames, at.speed or 15, at.blend or 0, false)
+ self.door_state = dstate
+ else
+ at=self.doors.close[self.door_state or 1]--in case it has not been set yet
+ self.object:set_animation(at.frames, at.speed or 15, at.blend or 0, false)
+ self.door_state = 0
+ end
+ self.door_anim_timer = at.time
end
- end
- else
- if self.discouple and self.discouple.object:getyaw() then
- self.discouple.object:remove()
+ else
+ self.door_anim_timer = (self.door_anim_timer or 0) - dtime
end
end
- end
- --for path to be available. if not, skip step
- if not gp.path then
- self.object:setvelocity({x=0, y=0, z=0})
- return
- end
- if not self.pos_in_train then
- --why ever. but better continue next step...
- advtrains.update_trainpart_properties(self.train_id)
- return
- end
-
- local index=advtrains.get_real_path_index(self:train(), self.pos_in_train)
- --atprint("trainindex "..gp.index.." wagonindex "..index)
-
- --automatic get_on
- --needs to know index and path
- if self.door_entry and gp.door_open and gp.door_open~=0 and gp.velocity==0 then
- --using the mapping created by the trainlogic globalstep
- for i, ino in ipairs(self.door_entry) do
- --fct is the flipstate flag from door animation above
- local aci = index + ino*fct
- local ix1=gp.path[math.floor(aci)]
- local ix2=gp.path[math.floor(aci+1)]
- -- the two wanted positions are ix1 and ix2 + (2nd-1st rotated by 90deg)
- -- (x z) rotated by 90deg is (-z x) (http://stackoverflow.com/a/4780141)
- local add = { x = (ix2.z-ix1.z)*gp.door_open, y = 0, z = (ix1.x-ix2.x)*gp.door_open }
- local pts1=vector.round(vector.add(ix1, add))
- local pts2=vector.round(vector.add(ix2, add))
- if minetest.get_item_group(minetest.get_node(pts1).name, "platform")>0 then
- local ckpts={
- pts1,
- pts2,
- vector.add(pts1, {x=0, y=1, z=0}),
- vector.add(pts2, {x=0, y=1, z=0}),
- }
- for _,ckpos in ipairs(ckpts) do
- local cpp=minetest.pos_to_string(ckpos)
- if advtrains.playersbypts[cpp] then
- self:on_rightclick(advtrains.playersbypts[cpp])
+
+ --DisCouple
+ if self.pos_in_trainparts and self.pos_in_trainparts>1 then
+ if gp.velocity==0 and not self.lock_couples then
+ if not self.discouple or not self.discouple.object:getyaw() then
+ local object=minetest.add_entity(pos, "advtrains:discouple")
+ if object then
+ local le=object:get_luaentity()
+ le.wagon=self
+ --box is hidden when attached, so unuseful.
+ --object:set_attach(self.object, "", {x=0, y=0, z=self.wagon_span*10}, {x=0, y=0, z=0})
+ self.discouple=le
+ else
+ atprint("Couldn't spawn DisCouple")
end
end
+ else
+ if self.discouple and self.discouple.object:getyaw() then
+ self.discouple.object:remove()
+ end
end
end
- end
-
- --position recalculation
- local first_pos=gp.path[math.floor(index)]
- local second_pos=gp.path[math.floor(index)+1]
- if not first_pos or not second_pos then
- --atprint(" object "..self.unique_id.." path end reached!")
- self.object:setvelocity({x=0,y=0,z=0})
- return
- end
-
- --checking for environment collisions(a 3x3 cube around the center)
- if not gp.recently_collided_with_env then
- local collides=false
- for x=-1,1 do
- for y=0,2 do
- for z=-1,1 do
- local node=minetest.get_node_or_nil(vector.add(first_pos, {x=x, y=y, z=z}))
- if (advtrains.train_collides(node)) then
- collides=true
+ --for path to be available. if not, skip step
+ if not gp.path then
+ self.object:setvelocity({x=0, y=0, z=0})
+ return
+ end
+ if not self.pos_in_train then
+ --why ever. but better continue next step...
+ advtrains.update_trainpart_properties(self.train_id)
+ return
+ end
+
+ local index=advtrains.get_real_path_index(self:train(), self.pos_in_train)
+ --atprint("trainindex "..gp.index.." wagonindex "..index)
+
+ --automatic get_on
+ --needs to know index and path
+ if self.door_entry and gp.door_open and gp.door_open~=0 and gp.velocity==0 then
+ --using the mapping created by the trainlogic globalstep
+ for i, ino in ipairs(self.door_entry) do
+ --fct is the flipstate flag from door animation above
+ local aci = index + ino*fct
+ local ix1=gp.path[math.floor(aci)]
+ local ix2=gp.path[math.floor(aci+1)]
+ -- the two wanted positions are ix1 and ix2 + (2nd-1st rotated by 90deg)
+ -- (x z) rotated by 90deg is (-z x) (http://stackoverflow.com/a/4780141)
+ local add = { x = (ix2.z-ix1.z)*gp.door_open, y = 0, z = (ix1.x-ix2.x)*gp.door_open }
+ local pts1=vector.round(vector.add(ix1, add))
+ local pts2=vector.round(vector.add(ix2, add))
+ if minetest.get_item_group(minetest.get_node(pts1).name, "platform")>0 then
+ local ckpts={
+ pts1,
+ pts2,
+ vector.add(pts1, {x=0, y=1, z=0}),
+ vector.add(pts2, {x=0, y=1, z=0}),
+ }
+ for _,ckpos in ipairs(ckpts) do
+ local cpp=minetest.pos_to_string(ckpos)
+ if advtrains.playersbypts[cpp] then
+ self:on_rightclick(advtrains.playersbypts[cpp])
+ end
end
end
end
end
- if collides then
- if self.collision_count and self.collision_count>10 then
- --enable collision mercy to get trains stuck in walls out of walls
- --actually do nothing except limiting the velocity to 1
- gp.velocity=math.min(gp.velocity, 1)
- gp.tarvelocity=math.min(gp.tarvelocity, 1)
+
+ --position recalculation
+ local first_pos=gp.path[math.floor(index)]
+ local second_pos=gp.path[math.floor(index)+1]
+ if not first_pos or not second_pos then
+ --atprint(" object "..self.unique_id.." path end reached!")
+ self.object:setvelocity({x=0,y=0,z=0})
+ return
+ end
+
+ --checking for environment collisions(a 3x3 cube around the center)
+ if not gp.recently_collided_with_env then
+ local collides=false
+ for x=-1,1 do
+ for y=0,2 do
+ for z=-1,1 do
+ local node=minetest.get_node_or_nil(vector.add(first_pos, {x=x, y=y, z=z}))
+ if (advtrains.train_collides(node)) then
+ collides=true
+ end
+ end
+ end
+ end
+ if collides then
+ if self.collision_count and self.collision_count>10 then
+ --enable collision mercy to get trains stuck in walls out of walls
+ --actually do nothing except limiting the velocity to 1
+ gp.velocity=math.min(gp.velocity, 1)
+ gp.tarvelocity=math.min(gp.tarvelocity, 1)
+ else
+ gp.recently_collided_with_env=true
+ gp.velocity=2*gp.velocity
+ gp.movedir=-gp.movedir
+ gp.tarvelocity=0
+ self.collision_count=(self.collision_count or 0)+1
+ end
else
- gp.recently_collided_with_env=true
- gp.velocity=2*gp.velocity
- gp.movedir=-gp.movedir
- gp.tarvelocity=0
- self.collision_count=(self.collision_count or 0)+1
+ self.collision_count=nil
end
+ end
+
+ --FIX: use index of the wagon, not of the train.
+ local velocity=(gp.velocity*gp.movedir)/(gp.path_dist[math.floor(index)] or 1)
+ local acceleration=(gp.last_accel or 0)/(gp.path_dist[math.floor(index)] or 1)
+ local factor=index-math.floor(index)
+ local actual_pos={x=first_pos.x-(first_pos.x-second_pos.x)*factor, y=first_pos.y-(first_pos.y-second_pos.y)*factor, z=first_pos.z-(first_pos.z-second_pos.z)*factor,}
+ local velocityvec={x=(first_pos.x-second_pos.x)*velocity*-1, z=(first_pos.z-second_pos.z)*velocity*-1, y=(first_pos.y-second_pos.y)*velocity*-1}
+ local accelerationvec={x=(first_pos.x-second_pos.x)*acceleration*-1, z=(first_pos.z-second_pos.z)*acceleration*-1, y=(first_pos.y-second_pos.y)*acceleration*-1}
+
+ --some additional positions to determine orientation
+ local aposfwd=gp.path[math.floor(index+2)]
+ local aposbwd=gp.path[math.floor(index-1)]
+
+ local yaw
+ if aposfwd and aposbwd then
+ yaw=advtrains.get_wagon_yaw(aposfwd, second_pos, first_pos, aposbwd, factor)+math.pi--TODO remove when cleaning up
else
- self.collision_count=nil
+ yaw=math.atan2((first_pos.x-second_pos.x), (second_pos.z-first_pos.z))
end
- end
-
- --FIX: use index of the wagon, not of the train.
- local velocity=(gp.velocity*gp.movedir)/(gp.path_dist[math.floor(index)] or 1)
- local acceleration=(gp.last_accel or 0)/(gp.path_dist[math.floor(index)] or 1)
- local factor=index-math.floor(index)
- local actual_pos={x=first_pos.x-(first_pos.x-second_pos.x)*factor, y=first_pos.y-(first_pos.y-second_pos.y)*factor, z=first_pos.z-(first_pos.z-second_pos.z)*factor,}
- local velocityvec={x=(first_pos.x-second_pos.x)*velocity*-1, z=(first_pos.z-second_pos.z)*velocity*-1, y=(first_pos.y-second_pos.y)*velocity*-1}
- local accelerationvec={x=(first_pos.x-second_pos.x)*acceleration*-1, z=(first_pos.z-second_pos.z)*acceleration*-1, y=(first_pos.y-second_pos.y)*acceleration*-1}
-
- --some additional positions to determine orientation
- local aposfwd=gp.path[math.floor(index+2)]
- local aposbwd=gp.path[math.floor(index-1)]
-
- local yaw
- if aposfwd and aposbwd then
- yaw=advtrains.get_wagon_yaw(aposfwd, second_pos, first_pos, aposbwd, factor)+math.pi--TODO remove when cleaning up
- else
- yaw=math.atan2((first_pos.x-second_pos.x), (second_pos.z-first_pos.z))
- end
- if self.wagon_flipped then
- yaw=yaw+math.pi
- end
-
- self.updatepct_timer=(self.updatepct_timer or 0)-dtime
- if not self.old_velocity_vector
- or not vector.equals(velocityvec, self.old_velocity_vector)
- or not self.old_acceleration_vector
- or not vector.equals(accelerationvec, self.old_acceleration_vector)
- or self.old_yaw~=yaw
- or self.updatepct_timer<=0 then--only send update packet if something changed
- self.object:setpos(actual_pos)
- self.object:setvelocity(velocityvec)
- self.object:setacceleration(accelerationvec)
- self.object:setyaw(yaw)
- self.updatepct_timer=2
- if self.update_animation then
- self:update_animation(gp.velocity)
+ if self.wagon_flipped then
+ yaw=yaw+math.pi
end
- end
-
-
- self.old_velocity_vector=velocityvec
- self.old_acceleration_vector=accelerationvec
- self.old_yaw=yaw
- atprintbm("wagon step", t)
+
+ self.updatepct_timer=(self.updatepct_timer or 0)-dtime
+ if not self.old_velocity_vector
+ or not vector.equals(velocityvec, self.old_velocity_vector)
+ or not self.old_acceleration_vector
+ or not vector.equals(accelerationvec, self.old_acceleration_vector)
+ or self.old_yaw~=yaw
+ or self.updatepct_timer<=0 then--only send update packet if something changed
+ self.object:setpos(actual_pos)
+ self.object:setvelocity(velocityvec)
+ self.object:setacceleration(accelerationvec)
+ self.object:setyaw(yaw)
+ self.updatepct_timer=2
+ if self.update_animation then
+ self:update_animation(gp.velocity)
+ end
+ end
+
+
+ self.old_velocity_vector=velocityvec
+ self.old_acceleration_vector=accelerationvec
+ self.old_yaw=yaw
+ atprintbm("wagon step", t)
+ end)
end
function advtrains.get_real_path_index(train, pit)
@@ -485,85 +491,87 @@ function advtrains.get_real_path_index(train, pit)
end
function wagon:on_rightclick(clicker)
- if not self:ensure_init() then return end
- if not clicker or not clicker:is_player() then
- return
- end
- if clicker:get_player_control().aux1 then
- --advtrains.dumppath(self:train().path)
- --minetest.chat_send_all("at index "..(self:train().index or "nil"))
- --advtrains.invert_train(self.train_id)
- atprint(dump(self))
- return
- end
- local pname=clicker:get_player_name()
- local no=self:get_seatno(pname)
- if no then
- if self.seat_groups then
- local poss={}
- local sgr=self.seats[no].group
- for _,access in ipairs(self.seat_groups[sgr].access_to) do
- if self:check_seat_group_access(pname, access) then
- poss[#poss+1]={name=self.seat_groups[access].name, key="sgr_"..access}
+ return advtrains.pcall(function()
+ if not self:ensure_init() then return end
+ if not clicker or not clicker:is_player() then
+ return
+ end
+ if clicker:get_player_control().aux1 then
+ --advtrains.dumppath(self:train().path)
+ --minetest.chat_send_all("at index "..(self:train().index or "nil"))
+ --advtrains.invert_train(self.train_id)
+ atprint(dump(self))
+ return
+ end
+ local pname=clicker:get_player_name()
+ local no=self:get_seatno(pname)
+ if no then
+ if self.seat_groups then
+ local poss={}
+ local sgr=self.seats[no].group
+ for _,access in ipairs(self.seat_groups[sgr].access_to) do
+ if self:check_seat_group_access(pname, access) then
+ poss[#poss+1]={name=self.seat_groups[access].name, key="sgr_"..access}
+ end
end
- end
- if self.has_inventory and self.get_inventory_formspec then
- poss[#poss+1]={name=attrans("Show Inventory"), key="inv"}
- end
- if self.owner==pname then
- poss[#poss+1]={name=attrans("Wagon properties"), key="prop"}
- end
- if not self.seat_groups[sgr].require_doors_open or self:train().door_open~=0 then
- poss[#poss+1]={name=attrans("Get off"), key="off"}
- else
- if clicker:get_player_control().sneak then
- poss[#poss+1]={name=attrans("Get off (forced)"), key="off"}
+ if self.has_inventory and self.get_inventory_formspec then
+ poss[#poss+1]={name=attrans("Show Inventory"), key="inv"}
+ end
+ if self.owner==pname then
+ poss[#poss+1]={name=attrans("Wagon properties"), key="prop"}
+ end
+ if not self.seat_groups[sgr].require_doors_open or self:train().door_open~=0 then
+ poss[#poss+1]={name=attrans("Get off"), key="off"}
else
- poss[#poss+1]={name=attrans("(Doors closed)"), key="dcwarn"}
+ if clicker:get_player_control().sneak then
+ poss[#poss+1]={name=attrans("Get off (forced)"), key="off"}
+ else
+ poss[#poss+1]={name=attrans("(Doors closed)"), key="dcwarn"}
+ end
end
- end
- if #poss==0 then
- --can't do anything.
- elseif #poss==1 then
- self:seating_from_key_helper(pname, {[poss[1].key]=true}, no)
- else
- local form = "size[5,"..1+(#poss).."]"
- for pos,ent in ipairs(poss) do
- form = form .. "button_exit[0.5,"..(pos-0.5)..";4,1;"..ent.key..";"..ent.name.."]"
+ if #poss==0 then
+ --can't do anything.
+ elseif #poss==1 then
+ self:seating_from_key_helper(pname, {[poss[1].key]=true}, no)
+ else
+ local form = "size[5,"..1+(#poss).."]"
+ for pos,ent in ipairs(poss) do
+ form = form .. "button_exit[0.5,"..(pos-0.5)..";4,1;"..ent.key..";"..ent.name.."]"
+ end
+ minetest.show_formspec(pname, "advtrains_seating_"..self.unique_id, form)
end
- minetest.show_formspec(pname, "advtrains_seating_"..self.unique_id, form)
+ else
+ self:get_off(no)
end
else
- self:get_off(no)
- end
- else
- --do not attach if already on a train
- if advtrains.player_to_train_mapping[pname] then return end
- if self.seat_groups then
- if #self.seats==0 then
- if self.has_inventory and self.get_inventory_formspec then
- minetest.show_formspec(pname, "advtrains_inv_"..self.unique_id, self:get_inventory_formspec(pname))
+ --do not attach if already on a train
+ if advtrains.player_to_train_mapping[pname] then return end
+ if self.seat_groups then
+ if #self.seats==0 then
+ if self.has_inventory and self.get_inventory_formspec then
+ minetest.show_formspec(pname, "advtrains_inv_"..self.unique_id, self:get_inventory_formspec(pname))
+ end
+ return
end
- return
- end
-
- local doors_open = self:train().door_open~=0 or clicker:get_player_control().sneak
- for _,sgr in ipairs(self.assign_to_seat_group) do
- if self:check_seat_group_access(pname, sgr) then
- for seatid, seatdef in ipairs(self.seats) do
- if seatdef.group==sgr and not self.seatp[seatid] and (not self.seat_groups[sgr].require_doors_open or doors_open) then
- self:get_on(clicker, seatid)
- return
+
+ local doors_open = self:train().door_open~=0 or clicker:get_player_control().sneak
+ for _,sgr in ipairs(self.assign_to_seat_group) do
+ if self:check_seat_group_access(pname, sgr) then
+ for seatid, seatdef in ipairs(self.seats) do
+ if seatdef.group==sgr and not self.seatp[seatid] and (not self.seat_groups[sgr].require_doors_open or doors_open) then
+ self:get_on(clicker, seatid)
+ return
+ end
end
end
end
+ minetest.chat_send_player(pname, attrans("Can't get on: wagon full or doors closed!"))
+ minetest.chat_send_player(pname, attrans("Use Sneak+rightclick to bypass closed doors!"))
+ else
+ self:show_get_on_form(pname)
end
- minetest.chat_send_player(pname, attrans("Can't get on: wagon full or doors closed!"))
- minetest.chat_send_player(pname, attrans("Use Sneak+rightclick to bypass closed doors!"))
- else
- self:show_get_on_form(pname)
end
- end
+ end)
end
function wagon:get_on(clicker, seatno)
@@ -708,77 +716,79 @@ function wagon:show_wagon_properties(pname)
minetest.show_formspec(pname, "advtrains_prop_"..self.unique_id, form)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
- local uid=string.match(formname, "^advtrains_geton_(.+)$")
- if uid then
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
- if fields.inv then
- if wagon.has_inventory and wagon.get_inventory_formspec then
- minetest.show_formspec(player:get_player_name(), "advtrains_inv_"..uid, wagon:get_inventory_formspec(player:get_player_name()))
- end
- elseif fields.seat then
- local val=minetest.explode_textlist_event(fields.seat)
- if val and val.type~="INV" and not wagon.seatp[player:get_player_name()] then
- --get on
- wagon:get_on(player, val.index)
- --will work with the new close_formspec functionality. close exactly this formspec.
- minetest.show_formspec(player:get_player_name(), formname, "")
+ return advtrains.pcall(function()
+ local uid=string.match(formname, "^advtrains_geton_(.+)$")
+ if uid then
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
+ if fields.inv then
+ if wagon.has_inventory and wagon.get_inventory_formspec then
+ minetest.show_formspec(player:get_player_name(), "advtrains_inv_"..uid, wagon:get_inventory_formspec(player:get_player_name()))
+ end
+ elseif fields.seat then
+ local val=minetest.explode_textlist_event(fields.seat)
+ if val and val.type~="INV" and not wagon.seatp[player:get_player_name()] then
+ --get on
+ wagon:get_on(player, val.index)
+ --will work with the new close_formspec functionality. close exactly this formspec.
+ minetest.show_formspec(player:get_player_name(), formname, "")
+ end
end
end
end
end
- end
- uid=string.match(formname, "^advtrains_seating_(.+)$")
- if uid then
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
- local pname=player:get_player_name()
- local no=wagon:get_seatno(pname)
- if no then
- if wagon.seat_groups then
- wagon:seating_from_key_helper(pname, fields, no)
+ uid=string.match(formname, "^advtrains_seating_(.+)$")
+ if uid then
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
+ local pname=player:get_player_name()
+ local no=wagon:get_seatno(pname)
+ if no then
+ if wagon.seat_groups then
+ wagon:seating_from_key_helper(pname, fields, no)
+ end
end
end
end
end
- end
- uid=string.match(formname, "^advtrains_prop_(.+)$")
- if uid then
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
- local pname=player:get_player_name()
- if pname~=wagon.owner then
- return true
- end
- if fields.save or not fields.quit then
- for sgr,sgrdef in pairs(wagon.seat_groups) do
- if fields["sgr_"..sgr] then
- local fcont = fields["sgr_"..sgr]
- wagon.seat_access[sgr] = fcont~="" and fcont or nil
- end
- end
- if fields.lock_couples then
- wagon.lock_couples = fields.lock_couples == "true"
+ uid=string.match(formname, "^advtrains_prop_(.+)$")
+ if uid then
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
+ local pname=player:get_player_name()
+ if pname~=wagon.owner then
+ return true
end
- if fields.text_outside then
- if fields.text_outside~="" then
- wagon:train().text_outside=fields.text_outside
- else
- wagon:train().text_outside=nil
+ if fields.save or not fields.quit then
+ for sgr,sgrdef in pairs(wagon.seat_groups) do
+ if fields["sgr_"..sgr] then
+ local fcont = fields["sgr_"..sgr]
+ wagon.seat_access[sgr] = fcont~="" and fcont or nil
+ end
end
- end
- if fields.text_inside then
- if fields.text_inside~="" then
- wagon:train().text_inside=fields.text_inside
- else
- wagon:train().text_inside=nil
+ if fields.lock_couples then
+ wagon.lock_couples = fields.lock_couples == "true"
+ end
+ if fields.text_outside then
+ if fields.text_outside~="" then
+ wagon:train().text_outside=fields.text_outside
+ else
+ wagon:train().text_outside=nil
+ end
+ end
+ if fields.text_inside then
+ if fields.text_inside~="" then
+ wagon:train().text_inside=fields.text_inside
+ else
+ wagon:train().text_inside=nil
+ end
end
+
end
-
end
end
end
- end
+ end)
end)
function wagon:seating_from_key_helper(pname, fields, no)
local sgr=self.seats[no].group
@@ -841,41 +851,43 @@ function advtrains.register_wagon(sysname, prototype, desc, inv_img)
stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
- if not pointed_thing.type == "node" then
- return
- end
-
+ return advtrains.pcall(function()
+ if not pointed_thing.type == "node" then
+ return
+ end
+
- local node=minetest.get_node_or_nil(pointed_thing.under)
- if not node then atprint("[advtrains]Ignore at placer position") return itemstack end
- local nodename=node.name
- if(not advtrains.is_track_and_drives_on(nodename, prototype.drives_on)) then
- atprint("no track here, not placing.")
+ local node=minetest.get_node_or_nil(pointed_thing.under)
+ if not node then atprint("[advtrains]Ignore at placer position") return itemstack end
+ local nodename=node.name
+ if(not advtrains.is_track_and_drives_on(nodename, prototype.drives_on)) then
+ atprint("no track here, not placing.")
+ return itemstack
+ end
+ if not minetest.check_player_privs(placer, {train_place = true }) and minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
+ minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
+ return
+ end
+ local conn1=advtrains.get_track_connections(node.name, node.param2)
+ local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1))
+
+ local ob=minetest.add_entity(pointed_thing.under, "advtrains:"..sysname)
+ if not ob then
+ atprint("couldn't add_entity, aborting")
+ end
+ local le=ob:get_luaentity()
+
+ le.owner=placer:get_player_name()
+
+ local wagon_uid=le:init_new_instance(id, {})
+
+ advtrains.add_wagon_to_train(le, id)
+ if not minetest.setting_getbool("creative_mode") then
+ itemstack:take_item()
+ end
return itemstack
- end
- if not minetest.check_player_privs(placer, {train_place = true }) and minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
- minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
- return
- end
- local conn1=advtrains.get_track_connections(node.name, node.param2)
- local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1))
-
- local ob=minetest.add_entity(pointed_thing.under, "advtrains:"..sysname)
- if not ob then
- atprint("couldn't add_entity, aborting")
- end
- local le=ob:get_luaentity()
-
- le.owner=placer:get_player_name()
-
- local wagon_uid=le:init_new_instance(id, {})
-
- advtrains.add_wagon_to_train(le, id)
- if not minetest.setting_getbool("creative_mode") then
- itemstack:take_item()
- end
- return itemstack
-
+
+ end)
end,
})
end
diff --git a/advtrains/advtrains_itrainmap/init.lua b/advtrains/advtrains_itrainmap/init.lua
index 85a3709..756f1da 100644
--- a/advtrains/advtrains_itrainmap/init.lua
+++ b/advtrains/advtrains_itrainmap/init.lua
@@ -136,7 +136,7 @@ function advtrains_itm_mainloop(dtime)
end
timer=2
end
-end)
+end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname=="itrainmap" and fields.quit then
itm_pdata[player:get_player_name()]=nil
diff --git a/advtrains/advtrains_luaautomation/init.lua b/advtrains/advtrains_luaautomation/init.lua
index b24bc01..0257aef 100644
--- a/advtrains/advtrains_luaautomation/init.lua
+++ b/advtrains/advtrains_luaautomation/init.lua
@@ -62,10 +62,10 @@ function atlatc.load()
end
file:close()
end
+ -- run init code of all environments
+ atlatc.run_initcode()
end
--- run init code of all environments
-atlatc.run_initcode()
atlatc.save = function()
--versions:
@@ -107,4 +107,4 @@ function atlatc.mainloop_stepcode(dtime)
timer=0
atlatc.run_stepcode()
end
-end)
+end
diff --git a/advtrains/advtrains_luaautomation/interrupt.lua b/advtrains/advtrains_luaautomation/interrupt.lua
index fa340b8..718b8c7 100644
--- a/advtrains/advtrains_luaautomation/interrupt.lua
+++ b/advtrains/advtrains_luaautomation/interrupt.lua
@@ -22,26 +22,24 @@ function iq.add(t, pos, evtdata)
end
function iq.mainloop(dtime)
- if run then
- timer=timer + math.min(dtime, 0.2)
- for i=1,#queue do
- local qe=queue[i]
- if not qe then
- table.remove(queue, i)
- i=i-1
- elseif timer>qe.t then
- local pos, evtdata=queue[i].p, queue[i].e
- local node=advtrains.ndb.get_node(pos)
- local ndef=minetest.registered_nodes[node.name]
- if ndef and ndef.luaautomation and ndef.luaautomation.fire_event then
- ndef.luaautomation.fire_event(pos, evtdata)
- end
- table.remove(queue, i)
- i=i-1
+ timer=timer + math.min(dtime, 0.2)
+ for i=1,#queue do
+ local qe=queue[i]
+ if not qe then
+ table.remove(queue, i)
+ i=i-1
+ elseif timer>qe.t then
+ local pos, evtdata=queue[i].p, queue[i].e
+ local node=advtrains.ndb.get_node(pos)
+ local ndef=minetest.registered_nodes[node.name]
+ if ndef and ndef.luaautomation and ndef.luaautomation.fire_event then
+ ndef.luaautomation.fire_event(pos, evtdata)
end
+ table.remove(queue, i)
+ i=i-1
end
end
-end)
+end