Maverick2797: 2 Turn loading tracks into loading ramps when within the loaded area Turn loading tracks into loading ramps when within the loaded area 4 files changed, 240 insertions(+), 65 deletions(-)
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
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
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
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>
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~gpcf/advtrains-devel/patches/41455/mbox | git am -3Learn more about email & git
- 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 true end - +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)) +end advtrains.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 true end - +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) +end advtrains.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