Discard get_node_or_nil() for area-loaded check and use either a distance-based approach or minetest.is_block_active() if available

See also https://github.com/minetest/minetest/pull/10897
This commit is contained in:
orwell96 2021-02-03 09:30:44 +01:00
parent d8d1d27ccb
commit 8ae405f00f
6 changed files with 39 additions and 30 deletions

View File

@ -106,7 +106,7 @@ minetest.register_entity("advtrains:couple", {
end,
on_step=function(self, dtime)
return advtrains.pcall(function()
if advtrains.outside_range(self.object:getpos()) then
if advtrains.wagon_outside_range(self.object:getpos()) then
self.object:remove()
return
end

View File

@ -445,3 +445,28 @@ atdebug("pts",os.clock()-t1,"s")
]]
-- Function to check whether a position is near (within range of) any player
function advtrains.position_in_range(pos, range)
if not pos then
return true
end
for _,p in pairs(minetest.get_connected_players()) do
if vector.distance(p:get_pos(),pos)<=range then
return true
end
end
return false
end
local active_node_range = tonumber(minetest.settings:get("active_block_range"))*16 + 16
-- Function to check whether node at position(pos) is "loaded"/"active"
-- That is, whether it is within the active_block_range to a player
if minetest.is_block_active then -- define function differently whether minetest.is_block_active is available or not
advtrains.is_node_loaded = minetest.is_block_active
else
function advtrains.is_node_loaded(pos)
if advtrains.position_in_range(pos, active_node_range) then
return true
end
end
end

View File

@ -223,7 +223,7 @@ end
function ndb.swap_node(pos, node, no_inval)
if minetest.get_node_or_nil(pos) then
if advtrains.is_node_loaded(pos) then
minetest.swap_node(pos, node)
end
ndb.update(pos, node)

View File

@ -527,7 +527,7 @@ function advtrains.train_step_c(id, train, dtime)
local collpos = advtrains.path_get(train, atround(collindex))
if collpos then
local rcollpos=advtrains.round_vector_floor_y(collpos)
local is_loaded_area = minetest.get_node_or_nil(rcollpos) ~= nil
local is_loaded_area = advtrains.is_node_loaded(rcollpos)
for x=-train.extent_h,train.extent_h do
for z=-train.extent_h,train.extent_h do
local testpos=vector.add(rcollpos, {x=x, y=0, z=z})
@ -870,14 +870,7 @@ function advtrains.spawn_wagons(train_id)
local index = advtrains.path_get_index_by_offset(train, train.index, -data.pos_in_train)
local pos = advtrains.path_get(train, atfloor(index))
local spawn = false
for _,p in pairs(minetest.get_connected_players()) do
if vector.distance(p:get_pos(),pos)<=ablkrng then
spawn = true
end
end
if spawn then
if advtrains.position_in_range(pos, ablkrng) then
--atdebug("wagon",w_id,"spawning")
local wt = advtrains.get_wagon_prototype(data)
local wagon = minetest.add_entity(pos, wt):get_luaentity()
@ -1032,7 +1025,7 @@ function advtrains.train_check_couples(train)
if not train.cpl_front then
-- recheck front couple
local front_trains, pos = advtrains.occ.get_occupations(train, atround(train.index) + CPL_CHK_DST)
if minetest.get_node_or_nil(pos) then -- if the position is loaded...
if advtrains.is_node_loaded(pos) then -- if the position is loaded...
for tid, idx in pairs(front_trains) do
local other_train = advtrains.trains[tid]
if not advtrains.train_ensure_init(tid, other_train) then
@ -1062,7 +1055,7 @@ function advtrains.train_check_couples(train)
if not train.cpl_back then
-- recheck back couple
local back_trains, pos = advtrains.occ.get_occupations(train, atround(train.end_index) - CPL_CHK_DST)
if minetest.get_node_or_nil(pos) then -- if the position is loaded...
if advtrains.is_node_loaded(pos) then -- if the position is loaded...
for tid, idx in pairs(back_trains) do
local other_train = advtrains.trains[tid]
if not advtrains.train_ensure_init(tid, other_train) then

View File

@ -15,19 +15,8 @@ advtrains.wagon_prototypes = {}
advtrains.wagon_objects = {}
local unload_wgn_range = advtrains.wagon_load_range + 32
function advtrains.outside_range(pos) -- returns true if the object is outside of unload_wgn_range of any player
-- this is part of a workaround until mintest core devs decide to fix a bug with static_save=false.
local outofrange = true
if not pos then
return true
end
for _,p in pairs(minetest.get_connected_players()) do
if vector.distance(p:get_pos(),pos)<=unload_wgn_range then
outofrange = false
break
end
end
return outofrange
function advtrains.wagon_outside_range(pos) -- returns true if the object is outside of unload_wgn_range of any player
return not advtrains.position_in_range(pos, unload_wgn_range)
end
local setting_show_ids = minetest.settings:get_bool("advtrains_show_ids")
@ -300,6 +289,8 @@ function wagon:on_step(dtime)
local train=self:train()
local is_in_loaded_area = advtrains.is_node_loaded(pos)
--custom on_step function
if self.custom_on_step then
self:custom_on_step(dtime, data, train)
@ -453,7 +444,7 @@ function wagon:on_step(dtime)
end
--checking for environment collisions(a 3x3 cube around the center)
if not train.recently_collided_with_env then
if is_in_loaded_area and not train.recently_collided_with_env then
local collides=false
local exh = self.extent_h or 1
local exv = self.extent_v or 2
@ -477,7 +468,7 @@ function wagon:on_step(dtime)
--DisCouple
-- FIX: Need to do this after the yaw calculation
if data.pos_in_trainparts and data.pos_in_trainparts>1 then
if is_in_loaded_area and data.pos_in_trainparts and data.pos_in_trainparts>1 then
if train.velocity==0 then
if not self.discouple or not self.discouple.object:getyaw() then
atprint(self.id,"trying to spawn discouple")
@ -530,7 +521,7 @@ function wagon:on_step(dtime)
end
end
if not players_in then
if advtrains.outside_range(pos) then
if advtrains.wagon_outside_range(pos) then
--atdebug("wagon",self.id,"unloading (too far away)")
-- Workaround until minetest engine deletes attached sounds
if self.sound_loop_handle then

View File

@ -101,7 +101,7 @@ function ac.run_in_env(pos, evtdata, customfct_p)
end
local meta
if minetest.get_node_or_nil(pos) then
if advtrains.is_node_loaded(pos) then
meta=minetest.get_meta(pos)
end