aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--advtrains.zipbin4991936 -> 4992868 bytes
-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
12 files changed, 815 insertions, 744 deletions
diff --git a/advtrains.zip b/advtrains.zip
index 02ab8b1..2144e28 100644
--- a/advtrains.zip
+++ b/advtrains.zip
Binary files differ
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