Parially addresses Hemiptera #165 / Notabug #6
This patch will turn the loading tracks from a flood loader to a loading ramp when in a loaded area.
Previous flood loading functionality retained when track is in unloaded area.
TODO/HELP: loading ramp does not trigger if track is in a loop. I believe this was noted for coupling previously too.
[PATCH] Turn loading tracks into loading ramps when within the loaded area
- Partially addresses Hemiptera #165 / Notabug #6
- Will recalculate wagon textures when the inventory is modified
- Only acts as a loading ramp when in a loaded area.
- Retains previous flood loading of entire train when area unloaded
- (?)TODO ramp doesn't activate if track is a closed loop.
---
advtrains_train_track/init.lua | 164 ++++++++++++++++++++-----advtrains_train_track/settingtypes.txt | 4 +
2 files changed, 136 insertions(+), 32 deletions(-)
mode change 100755 => 100644 advtrains_train_track/init.lua
create mode 100644 advtrains_train_track/settingtypes.txt
diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua
old mode 100755
new mode 100644
index 5065155..a1fd0b1
--- a/advtrains_train_track/init.lua+++ b/advtrains_train_track/init.lua
@@ -678,8 +678,49 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end)
+local function load_wagon(wagon_id, node_inv, node_fc, unload)+ local inv_modified = false+ local w_inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..wagon_id})+ if w_inv and w_inv:get_list("box") then++ local wagon_data = advtrains.wagons[wagon_id]+ local wagon_fc+ if wagon_data.fc then+ if not wagon_data.fcind then wagon_data.fcind = 1 end+ wagon_fc = tostring(wagon_data.fc[wagon_data.fcind]) or ""+ end++ if node_fc == "" or wagon_fc == node_fc then+ if not unload then+-- atdebug("wagon id: "..wagon_id.." loaded")+ for _, item in ipairs(node_inv:get_list("main")) do+ if w_inv:get_list("box") and w_inv:room_for_item("box", item) then+ w_inv:add_item("box", item)+ node_inv:remove_item("main", item)+ if item.name ~= "" then inv_modified = true end+ end+ end+ else+-- atdebug("wagon id: "..wagon_id.." unloaded")+ for _, item in ipairs(w_inv:get_list("box")) do+ if node_inv:get_list("main") and node_inv:room_for_item("main", item) then+ w_inv:remove_item("box", item)+ node_inv:add_item("main", item)+ if item.name ~= "" then inv_modified = true end+ end+ end+ end+ end+ end+ return inv_modified+end-local function train_load(pos, train_id, unload)+local function load_entire_train(pos, train_id, unload) -- flood load when not in an active area+ if advtrains.is_node_loaded(pos) then -- leave the loading to the nodetimer if area is loaded+-- atdebug("area loaded")+ return + end+-- atdebug("area unloaded ======================") local train=advtrains.trains[train_id]
local below = get_far_node({x=pos.x, y=pos.y-1, z=pos.z})
if not string.match(below.name, "chest") then
@@ -692,43 +733,88 @@ local function train_load(pos, train_id, unload)
--track section is disabled
return
end
-- local inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})- if inv and train.velocity < 2 then- for k, v in ipairs(train.trainparts) do- local i=minetest.get_inventory({type="detached", name="advtrains_wgn_"..v})- if i and i:get_list("box") then-- local wagon_data = advtrains.wagons[v]- local wagon_fc- if wagon_data.fc then- if not wagon_data.fcind then wagon_data.fcind = 1 end- wagon_fc = tostring(wagon_data.fc[wagon_data.fcind]) or ""- end-- if node_fc == "" or wagon_fc == node_fc then- if not unload then- for _, item in ipairs(inv:get_list("main")) do- if i:get_list("box") and i:room_for_item("box", item) then- i:add_item("box", item)- inv:remove_item("main", item)- end- end- else- for _, item in ipairs(i:get_list("box")) do- if inv:get_list("main") and inv:room_for_item("main", item) then- i:remove_item("box", item)- inv:add_item("main", item)- end+-- atdebug("pre-checks passed")+ local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})+ if node_inv and train.velocity <= 2 then+-- atdebug(train)+ for _, wagon_id in ipairs(train.trainparts) do+ load_wagon(wagon_id, node_inv, node_fc, unload)+ end+ end+-- atdebug("flood loading complete ==========================")+end++local function load_wagon_on_timer(pos, unload) -- loading ramp when in an active area+-- atdebug("=========")+-- atdebug((get_far_node(pos).name == "advtrains:dtrack_unload_st" and "unloader") or "loading track")+-- atdebug("ping")+ if not advtrains.is_node_loaded(pos) then -- leave the loading for the flood load function. we're out of area+ return true -- reset the nodetimer until the node is loaded again+ end+-- atdebug("area is loaded")+ local tid, tidx = advtrains.get_train_at_pos(pos)+-- atdebug("got train:")+-- atdebug(tostring(tid))+-- atdebug(tidx)+ if not tid or tid == "" then+-- atdebug("no train")+ return true+ end -- no train to load.+-- atdebug("is train: "..tostring(tid).." <--")+ local train = advtrains.trains[tid]+-- atdebug("train exists: ")+-- atdebug(train)+ local below = get_far_node({x=pos.x, y=pos.y-1, z=pos.z})+ if not string.match(below.name, "chest") then+ atprint("this is not a chest! at "..minetest.pos_to_string(pos))+ return true+ end+-- atdebug("is chest")+ local node_fc = minetest.get_meta(pos):get_string("fc") or ""+ if node_fc == "#" then+ --track section is disabled+ return true+ end+-- atdebug("FC: "..node_fc)+ local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})+ if node_inv and train.velocity <= 2 then+-- atdebug("begin wagon checks")+ local _, wagon_id, wagon_data = advtrains.get_wagon_at_index(tid, tidx)+ if wagon_id then+ local inv_modified = load_wagon(wagon_id, node_inv, node_fc, unload)+ if inv_modified then+-- atdebug("==================INVENTORY MODIFIED " .. wagon_id .." - " .. tostring(inv_modified))+-- atdebug("=================Wagon Data")+-- atdebug(wagon_data)+-- atdebug("=================Wagon Prototype")+-- print(dump(advtrains.wagon_prototypes[advtrains.get_wagon_prototype(wagon_data)]))+ if advtrains.wagon_prototypes[advtrains.get_wagon_prototype(wagon_data)].set_textures then+-- atdebug("================has set_textures function")+ local wagon_object = advtrains.wagon_objects[wagon_id]+ if wagon_object and wagon_data then+-- atdebug("================obj and data ok")+ local ent = wagon_object:get_luaentity()+ if ent and ent.set_textures then+-- atdebug("================set_texture funtion found")+ ent:set_textures(wagon_data)+-- atdebug("===============textures updated") end
end
end
end
+-- atdebug(wagon_id.." "..tostring(unload)) end
end
+-- atdebug("End loading ramp ===================")+ return trueend
-+local nodetimer_interval = minetest.settings:get("advtrains_loading_track_timer") or 1+local function start_nodetimer(pos)+ local timer = minetest.get_node_timer(pos)+ timer:start(nodetimer_interval)+-- atdebug("timer started at "..minetest.pos_to_string(pos))+endadvtrains.register_tracks("default", {
nodename_prefix="advtrains:dtrack_unload",
@@ -747,9 +833,16 @@ advtrains.register_tracks("default", {
on_rightclick = function(pos, node, player)
show_fc_formspec(pos, player)
end,
+ after_place_node = function(pos)+ advtrains.ndb.update(pos)+ start_nodetimer(pos)+ end,+ on_timer = function(pos)+ return load_wagon_on_timer(pos, true)+ end, advtrains = {
on_train_enter = function(pos, train_id)
- train_load(pos, train_id, true)+ load_entire_train(pos, train_id, true) end,
},
}
@@ -772,9 +865,16 @@ advtrains.register_tracks("default", {
on_rightclick = function(pos, node, player)
show_fc_formspec(pos, player)
end,
+ after_place_node = function(pos)+ advtrains.ndb.update(pos)+ start_nodetimer(pos)+ end,+ on_timer = function(pos)+ return load_wagon_on_timer(pos, false)+ end, advtrains = {
on_train_enter = function(pos, train_id)
- train_load(pos, train_id, false)+ load_entire_train(pos, train_id, false) end,
},
}
diff --git a/advtrains_train_track/settingtypes.txt b/advtrains_train_track/settingtypes.txt
new file mode 100644
index 0000000..0af0081
--- /dev/null+++ b/advtrains_train_track/settingtypes.txt
@@ -0,0 +1,4 @@
+# Set the nodetimer delay for the loading tracks.+# A longer delay may cause wagons to be missed if the pass over too fast.+# A shorter delay may cause lag as wagons are checked multiple times as they pass over.+advtrains_loading_track_timer (Loading Track Timer) int 1
\ No newline at end of file
--
2.38.0
- Partially addresses Hemiptera #165 / Notabug #6
- Will recalculate wagon textures when the inventory is modified
- Only acts as a loading ramp when in a loaded area.
- Retains previous flood loading of entire train when area unloaded
- (?)TODO ramp doesn't activate if track is a closed loop.
---
advtrains_train_track/init.lua | 133 +++++++++++++++++++------advtrains_train_track/settingtypes.txt | 4 +
2 files changed, 104 insertions(+), 33 deletions(-)
mode change 100755 => 100644 advtrains_train_track/init.lua
create mode 100644 advtrains_train_track/settingtypes.txt
diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua
old mode 100755
new mode 100644
index 5065155..32e1235
--- a/advtrains_train_track/init.lua+++ b/advtrains_train_track/init.lua
@@ -678,8 +678,45 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end)
+local function load_wagon(wagon_id, node_inv, node_fc, unload)+ local inv_modified = false+ local w_inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..wagon_id})+ if w_inv and w_inv:get_list("box") then++ local wagon_data = advtrains.wagons[wagon_id]+ local wagon_fc+ if wagon_data.fc then+ if not wagon_data.fcind then wagon_data.fcind = 1 end+ wagon_fc = tostring(wagon_data.fc[wagon_data.fcind]) or ""+ end++ if node_fc == "" or wagon_fc == node_fc then+ if not unload then+ for _, item in ipairs(node_inv:get_list("main")) do+ if w_inv:get_list("box") and w_inv:room_for_item("box", item) then+ w_inv:add_item("box", item)+ node_inv:remove_item("main", item)+ if item.name ~= "" then inv_modified = true end+ end+ end+ else+ for _, item in ipairs(w_inv:get_list("box")) do+ if node_inv:get_list("main") and node_inv:room_for_item("main", item) then+ w_inv:remove_item("box", item)+ node_inv:add_item("main", item)+ if item.name ~= "" then inv_modified = true end+ end+ end+ end+ end+ end+ return inv_modified+end-local function train_load(pos, train_id, unload)+local function load_entire_train(pos, train_id, unload) -- flood load when not in an active area+ if advtrains.is_node_loaded(pos) then -- leave the loading to the nodetimer if area is loaded+ return + end local train=advtrains.trains[train_id]
local below = get_far_node({x=pos.x, y=pos.y-1, z=pos.z})
if not string.match(below.name, "chest") then
@@ -692,43 +729,60 @@ local function train_load(pos, train_id, unload)
--track section is disabled
return
end
-- local inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})- if inv and train.velocity < 2 then- for k, v in ipairs(train.trainparts) do- local i=minetest.get_inventory({type="detached", name="advtrains_wgn_"..v})- if i and i:get_list("box") then-- local wagon_data = advtrains.wagons[v]- local wagon_fc- if wagon_data.fc then- if not wagon_data.fcind then wagon_data.fcind = 1 end- wagon_fc = tostring(wagon_data.fc[wagon_data.fcind]) or ""- end-- if node_fc == "" or wagon_fc == node_fc then- if not unload then- for _, item in ipairs(inv:get_list("main")) do- if i:get_list("box") and i:room_for_item("box", item) then- i:add_item("box", item)- inv:remove_item("main", item)- end- end- else- for _, item in ipairs(i:get_list("box")) do- if inv:get_list("main") and inv:room_for_item("main", item) then- i:remove_item("box", item)- inv:add_item("main", item)- end+ local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})+ if node_inv and train.velocity <= 2 then+ for _, wagon_id in ipairs(train.trainparts) do+ load_wagon(wagon_id, node_inv, node_fc, unload)+ end+ end+end++local function load_wagon_on_timer(pos, unload) -- loading ramp when in an active area+ if not advtrains.is_node_loaded(pos) then -- leave the loading for the flood load function. we're out of area+ return true -- reset the nodetimer until the node is loaded again+ end+ local tid, tidx = advtrains.get_train_at_pos(pos)+ if not tid or tid == "" then+ return true+ end -- no train to load.++ local train = advtrains.trains[tid]+ local below = get_far_node({x=pos.x, y=pos.y-1, z=pos.z})+ if not string.match(below.name, "chest") then+ atprint("this is not a chest! at "..minetest.pos_to_string(pos))+ return true+ end+ local node_fc = minetest.get_meta(pos):get_string("fc") or ""+ if node_fc == "#" then+ --track section is disabled+ return true+ end+ local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})+ if node_inv and train.velocity <= 2 then+ local _, wagon_id, wagon_data = advtrains.get_wagon_at_index(tid, tidx)+ if wagon_id then+ local inv_modified = load_wagon(wagon_id, node_inv, node_fc, unload)+ if inv_modified then+ if advtrains.wagon_prototypes[advtrains.get_wagon_prototype(wagon_data)].set_textures then+ local wagon_object = advtrains.wagon_objects[wagon_id]+ if wagon_object and wagon_data then+ local ent = wagon_object:get_luaentity()+ if ent and ent.set_textures then+ ent:set_textures(wagon_data) end
end
end
end
end
end
+ return trueend
-+local nodetimer_interval = minetest.settings:get("advtrains_loading_track_timer") or 1+local function start_nodetimer(pos)+ local timer = minetest.get_node_timer(pos)+ timer:start(nodetimer_interval)+endadvtrains.register_tracks("default", {
nodename_prefix="advtrains:dtrack_unload",
@@ -747,9 +801,16 @@ advtrains.register_tracks("default", {
on_rightclick = function(pos, node, player)
show_fc_formspec(pos, player)
end,
+ after_place_node = function(pos)+ advtrains.ndb.update(pos)+ start_nodetimer(pos)+ end,+ on_timer = function(pos)+ return load_wagon_on_timer(pos, true)+ end, advtrains = {
on_train_enter = function(pos, train_id)
- train_load(pos, train_id, true)+ load_entire_train(pos, train_id, true) end,
},
}
@@ -772,9 +833,16 @@ advtrains.register_tracks("default", {
on_rightclick = function(pos, node, player)
show_fc_formspec(pos, player)
end,
+ after_place_node = function(pos)+ advtrains.ndb.update(pos)+ start_nodetimer(pos)+ end,+ on_timer = function(pos)+ return load_wagon_on_timer(pos, false)+ end, advtrains = {
on_train_enter = function(pos, train_id)
- train_load(pos, train_id, false)+ load_entire_train(pos, train_id, false) end,
},
}
@@ -788,7 +856,6 @@ if minetest.get_modpath("basic_materials") then
elseif minetest.get_modpath("technic") then
loader_core = "technic:control_logic_unit"
end
---print("Loader Core: "..loader_core)minetest.register_craft({
type="shapeless",
diff --git a/advtrains_train_track/settingtypes.txt b/advtrains_train_track/settingtypes.txt
new file mode 100644
index 0000000..0af0081
--- /dev/null+++ b/advtrains_train_track/settingtypes.txt
@@ -0,0 +1,4 @@
+# Set the nodetimer delay for the loading tracks.+# A longer delay may cause wagons to be missed if the pass over too fast.+# A shorter delay may cause lag as wagons are checked multiple times as they pass over.+advtrains_loading_track_timer (Loading Track Timer) int 1
\ No newline at end of file
--
2.38.0
[PATCH] Turn loading tracks into loading ramps when within the loaded area
Hi,
- (?)TODO ramp doesn't activate if track is a closed loop.
Oh no. This issue is slowly becoming a nightmare. It breaks the
coupling system, it breaks path projection, it breaks the loading
rails...
There needs to be done a change in the occupation system, so that it
can handle the same train having this position at multiple path
items (or at least make the lowest index take precedence)
I need to think about that separately.
orwell
Re: [PATCH] Turn loading tracks into loading ramps when within the loaded area
Hi Maverick,
I have pushed a commit to master fixing the issue with the track loops.
Can you rebase your patch onto this and test it? Once it works I would
like to merge it and maybe even publish a release (there hasn't been
one for some time). Thank you!
Regards, orwell
Re: [PATCH] Turn loading tracks into loading ramps when within the loaded area
The commit doesn't seem to have affected the loading ramps at all,
however it does cause a crash if the track ahead of the train is changed.
I first noticed it when a detector track changed state underneath the
loco, and was able to reproduce it both by changing a turnout and
replacing track ahead of the train.
2023-06-24 21:46:45: ERROR[Main]: ServerError: AsyncErr: Lua: Runtime
error from mod '' in callback item_OnPlace():
...0-release-win64\bin\..\mods\advtrains\advtrains/path.lua:165: attempt
to call field 'clear_item' (a nil value)
2023-06-24 21:46:45: ERROR[Main]: stack traceback:
2023-06-24 21:46:45: ERROR[Main]:
...0-release-win64\bin\..\mods\advtrains\advtrains/path.lua:165: in
function 'path_invalidate_ahead'
2023-06-24 21:46:45: ERROR[Main]:
...ase-win64\bin\..\mods\advtrains\advtrains/trainlogic.lua:1263: in
function 'invalidate_all_paths_ahead'
2023-06-24 21:46:45: ERROR[Main]:
...release-win64\bin\..\mods\advtrains\advtrains/nodedb.lua:251: in
function 'update'
2023-06-24 21:46:45: ERROR[Main]:
...release-win64\bin\..\mods\advtrains\advtrains/nodedb.lua:231: in
function 'swap_node'
2023-06-24 21:46:45: ERROR[Main]:
...se-win64\bin\..\mods\advtrains\advtrains/trackplacer.lua:220: in
function 'placetrack'
2023-06-24 21:46:45: ERROR[Main]:
...se-win64\bin\..\mods\advtrains\advtrains/trackplacer.lua:298: in
function <...se-win64\bin\..\mods\advtrains\advtrains/trackplacer.lua:277>
Re: [PATCH] Turn loading tracks into loading ramps when within the loaded area
Hi Maverick,
Thanks for reporting this, I oversaw one call in path_invalidate_ahead.
Should be fixed now, please try again whether the unloading rails now
work correctly in track loops.
Regards, orwell