forked from VoxeLibre/VoxeLibre
Compare commits
1 Commits
master
...
faster-wor
Author | SHA1 | Date |
---|---|---|
teknomunk | 3ad862c61c |
|
@ -146,60 +146,87 @@ local function good_for_respawn(pos, player)
|
||||||
local def0 = minetest.registered_nodes[nn0]
|
local def0 = minetest.registered_nodes[nn0]
|
||||||
local def1 = minetest.registered_nodes[nn1]
|
local def1 = minetest.registered_nodes[nn1]
|
||||||
local def2 = minetest.registered_nodes[nn2]
|
local def2 = minetest.registered_nodes[nn2]
|
||||||
|
|
||||||
|
-- Be safe around undefined nodes
|
||||||
|
if not def0 then return false end
|
||||||
|
if not def1 then return false end
|
||||||
|
if not def2 then return false end
|
||||||
|
|
||||||
return def0.walkable and (not def1.walkable) and (not def2.walkable) and
|
return def0.walkable and (not def1.walkable) and (not def2.walkable) and
|
||||||
(def1.damage_per_second == nil or def2.damage_per_second <= 0) and
|
(def1.damage_per_second == nil or def2.damage_per_second <= 0) and
|
||||||
(def1.damage_per_second == nil or def2.damage_per_second <= 0)
|
(def1.damage_per_second == nil or def2.damage_per_second <= 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function can_find_tree(pos1, trees)
|
|
||||||
if not emerge_pos1 or not emerge_pos2 then return false end
|
|
||||||
local trees = trees or get_trees(pos1)
|
|
||||||
if not trees then return false end
|
|
||||||
|
|
||||||
if (attempts_to_find_trees * 3 < #trees) then
|
local ADJACENT_OFFSETS = {
|
||||||
-- random search
|
vector.new( 1,0, 0),
|
||||||
for i = 1, attempts_to_find_trees do
|
vector.new(-1,0, 0),
|
||||||
local pos2 = trees[math.random(1,#trees)]
|
vector.new( 0,0, 1),
|
||||||
if not minetest.is_protected(pos2, "") then
|
vector.new( 0,0,-1),
|
||||||
if pos2.x < pos1.x then
|
vector.new( 0,1, 0),
|
||||||
pos2.x = pos2.x + 1
|
}
|
||||||
elseif pos2.x > pos1.x then
|
|
||||||
pos2.x = pos2.x - 1
|
local function pathfind_next_to(target, pos1, distance)
|
||||||
end
|
local closest_free_pos = nil
|
||||||
if pos2.z < pos1.z then
|
local closest_free_dist = nil
|
||||||
pos2.z = pos2.z + 1
|
for j=1,4 do
|
||||||
elseif pos2.z > pos1.z then
|
local test_pos = vector.add(target, ADJACENT_OFFSETS[j])
|
||||||
pos2.z = pos2.z - 1
|
if minetest.get_node(test_pos).name == "air" and minetest.get_node(vector.offset(test_pos,0,-1,0)).name ~= "air" then
|
||||||
end
|
local new_dist = vector.distance(pos1, test_pos)
|
||||||
local way = minetest.find_path(pos1, pos2, res, 1, 3, "A*_noprefetch")
|
if not closest_free_pos or new_dist < closest_free_dist then
|
||||||
if way then
|
closest_free_pos = test_pos
|
||||||
return true
|
closest_free_dist = new_dist
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local way = false
|
||||||
|
if closest_free_pos then
|
||||||
|
return minetest.find_path(pos1, closest_free_pos, distance, 1, 3, "A*_noprefetch")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function can_find_tree(pos1, trees)
|
||||||
|
local start_time = minetest.get_us_time()
|
||||||
|
|
||||||
|
if not emerge_pos1 or not emerge_pos2 then
|
||||||
|
minetest.log("verbose", "[mcl_spawn] Missing emerge position in can_find_tree()")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local trees = trees or get_trees(pos1)
|
||||||
|
if not trees then
|
||||||
|
minetest.log("verbose", "[mcl_spawn] No trees in area in can_find_tree()")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, pos2 in ipairs(trees) do
|
-- Search from closest to furthest from pos1
|
||||||
-- full search
|
for i = 2,#trees do
|
||||||
if not minetest.is_protected(pos2, "") then
|
for j = 1,(i-1) do
|
||||||
if pos2.x < pos1.x then
|
if vector.distance(pos1,trees[j]) > vector.distance(pos1,trees[j+1]) then
|
||||||
pos2.x = pos2.x + 1
|
local tmp = trees[j+1]
|
||||||
elseif pos2.x > pos1.x then
|
trees[j] = trees[j+1]
|
||||||
pos2.x = pos2.x - 1
|
trees[j+1] = tmp
|
||||||
end
|
|
||||||
if pos2.z < pos1.z then
|
|
||||||
pos2.z = pos2.z + 1
|
|
||||||
elseif pos2.z > pos1.z then
|
|
||||||
pos2.z = pos2.z - 1
|
|
||||||
end
|
|
||||||
local way = minetest.find_path(pos1, pos2, res, 1, 3, "A*_noprefetch")
|
|
||||||
if way then
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if i > attempts_to_find_trees then return false end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for i = 1,#trees do
|
||||||
|
local possible_tree = trees[i]
|
||||||
|
|
||||||
|
local start_pathfind = minetest.get_us_time()
|
||||||
|
local way = pathfind_next_to(possible_tree, pos1, res)
|
||||||
|
local stop_pathfind = minetest.get_us_time()
|
||||||
|
|
||||||
|
if stop_pathfind > start_time + 0.25e6 then
|
||||||
|
minetest.log("info","[mcl_spawn] can_find_tree() timed out")
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
if way then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -285,86 +312,52 @@ local function next_biome()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function find_spawn_in_area(pos1, pos2)
|
||||||
|
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"group:tree"})
|
||||||
|
if #nodes <= 0 then return nil end
|
||||||
|
|
||||||
|
for i = 1,#nodes do
|
||||||
|
local pos = nodes[i]
|
||||||
|
|
||||||
|
local candidates = minetest.find_nodes_in_area_under_air(
|
||||||
|
vector.offset(pos,-3,-2,-3),
|
||||||
|
vector.offset(pos, 3, 2, 3),
|
||||||
|
{"group:solid"}
|
||||||
|
)
|
||||||
|
|
||||||
|
for j = 1,#candidates do
|
||||||
|
local candidate = vector.offset(candidates[j],0,1,0)
|
||||||
|
local gfs = good_for_respawn(candidate)
|
||||||
|
local way = false
|
||||||
|
if vector.distance(candidate, pos) <= 1 then
|
||||||
|
way = true
|
||||||
|
else
|
||||||
|
local way = pathfind_next_to(candidate, pos, 5)
|
||||||
|
end
|
||||||
|
if gfs and way then
|
||||||
|
return candidate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local function ecb_search_continue(blockpos, action, calls_remaining, param)
|
local function ecb_search_continue(blockpos, action, calls_remaining, param)
|
||||||
if calls_remaining <= 0 then
|
if calls_remaining <= 0 then
|
||||||
emerge_pos1 = {x = wsp.x-half_res, y = alt_min, z = wsp.z-half_res}
|
emerge_pos1 = {x = wsp.x-half_res, y = alt_min, z = wsp.z-half_res}
|
||||||
emerge_pos2 = {x = wsp.x+half_res, y = alt_max, z = wsp.z+half_res}
|
emerge_pos2 = {x = wsp.x+half_res, y = alt_max, z = wsp.z+half_res}
|
||||||
local nodes = minetest.find_nodes_in_area_under_air(emerge_pos1, emerge_pos2, node_groups_white_list)
|
local start_time = minetest.get_us_time()
|
||||||
minetest.log("verbose", "[mcl_spawn] Data emerge callback: "..minetest.pos_to_string(wsp).." - "..tostring(nodes and #nodes) .. " node(s) found under air")
|
|
||||||
if nodes then
|
local spawn_pos = find_spawn_in_area(emerge_pos1, emerge_pos2)
|
||||||
if no_trees_area_counter >= 0 then
|
if spawn_pos then
|
||||||
local trees = get_trees(emerge_pos1, emerge_pos2)
|
wsp = spawn_pos
|
||||||
if trees and #trees > 0 then
|
minetest.log("action", "[mcl_spawn] Dynamic world spawn randomly determined to be "..minetest.pos_to_string(wsp))
|
||||||
no_trees_area_counter = 0
|
searched = true
|
||||||
if attempts_to_find_pos * 3 < #nodes then
|
success = true
|
||||||
-- random
|
return
|
||||||
for i=1, attempts_to_find_pos do
|
|
||||||
wsp = nodes[math.random(1,#nodes)]
|
|
||||||
if wsp then
|
|
||||||
wsp.y = wsp.y + 1
|
|
||||||
if good_for_respawn(wsp) and can_find_tree(wsp, trees) then
|
|
||||||
minetest.log("action", "[mcl_spawn] Dynamic world spawn randomly determined to be "..minetest.pos_to_string(wsp))
|
|
||||||
searched = true
|
|
||||||
success = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- in a sequence
|
|
||||||
for i=1, math.min(#nodes, attempts_to_find_pos) do
|
|
||||||
wsp = nodes[i]
|
|
||||||
if wsp then
|
|
||||||
wsp.y = wsp.y + 1
|
|
||||||
if good_for_respawn(wsp) and can_find_tree(wsp, trees) then
|
|
||||||
minetest.log("action", "[mcl_spawn] Dynamic world spawn determined to be "..minetest.pos_to_string(wsp))
|
|
||||||
searched = true
|
|
||||||
success = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
no_trees_area_counter = no_trees_area_counter + 1
|
|
||||||
if no_trees_area_counter > 10 then
|
|
||||||
minetest.log("verbose", "[mcl_spawn] More than 10 times no trees at all! Won't search trees next 200 calls")
|
|
||||||
no_trees_area_counter = -200
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else -- seems there are no trees but we'll check it later, after next 200 calls
|
|
||||||
no_trees_area_counter = no_trees_area_counter + 1
|
|
||||||
if attempts_to_find_pos * 3 < #nodes then
|
|
||||||
-- random
|
|
||||||
for i=1, attempts_to_find_pos do
|
|
||||||
wsp = nodes[math.random(1,#nodes)]
|
|
||||||
if wsp then
|
|
||||||
wsp.y = wsp.y + 1
|
|
||||||
if good_for_respawn(wsp) then
|
|
||||||
minetest.log("action", "[mcl_spawn] Dynamic world spawn randomly determined to be "..minetest.pos_to_string(wsp) .. " (no trees)")
|
|
||||||
searched = true
|
|
||||||
success = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- in a sequence
|
|
||||||
for i=1, math.min(#nodes, attempts_to_find_pos) do
|
|
||||||
wsp = nodes[i]
|
|
||||||
if wsp then
|
|
||||||
wsp.y = wsp.y + 1
|
|
||||||
if good_for_respawn(wsp) then
|
|
||||||
minetest.log("action", "[mcl_spawn] Dynamic world spawn determined to be "..minetest.pos_to_string(wsp) .. " (no trees)")
|
|
||||||
searched = true
|
|
||||||
success = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
next_pos()
|
next_pos()
|
||||||
mcl_spawn.search()
|
mcl_spawn.search()
|
||||||
end
|
end
|
||||||
|
@ -565,8 +558,24 @@ function mcl_spawn.shadow_worker()
|
||||||
|
|
||||||
if success then
|
if success then
|
||||||
local wsp_node = minetest.get_node(wsp)
|
local wsp_node = minetest.get_node(wsp)
|
||||||
if not (wsp_node and wsp_node.name == "ignore")
|
local spawn_bad = false
|
||||||
and ((not good_for_respawn(wsp)) or ((no_trees_area_counter >= 0) and not can_find_tree(wsp))) then
|
|
||||||
|
if not spawn_bad and not wsp_node or wsp_node.name == "ignore" then
|
||||||
|
spawn_bad = true
|
||||||
|
minetest.log("verbose", "[mcl_spawn] World spawn point could not be checked or is 'ignore' wsp_node="..dump(wsp_node))
|
||||||
|
end
|
||||||
|
|
||||||
|
if not spawn_bad and not good_for_respawn(wsp) then
|
||||||
|
spawn_bad = true
|
||||||
|
minetest.log("verbose", "[mcl_spawn] World spawn point is not good for respawn")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not spawn_bad and ( (no_trees_area_counter >= 0) and not can_find_tree(wsp) ) then
|
||||||
|
spawn_bad = true
|
||||||
|
minetest.log("verbose", "[mcl_spawn] No trees near spawn point")
|
||||||
|
end
|
||||||
|
|
||||||
|
if spawn_bad then
|
||||||
success = false
|
success = false
|
||||||
minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp))
|
minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp))
|
||||||
mcl_spawn.search()
|
mcl_spawn.search()
|
||||||
|
|
Loading…
Reference in New Issue