mirror of
https://git.minetest.land/MineClone2/MineClone2.git
synced 2024-11-28 05:43:43 +01:00
Improve Nether Portals (#1315) (as a squash)
Remove Nether portal caches, https://git.minetest.land/MineClone2/MineClone2/issues/1210 Store all exits from Nether portals in quick-access table Implement proper Nether portal search, using the table, https://git.minetest.land/MineClone2/MineClone2/issues/1055 Store Nether portal exits table in mod storage Remove exits from table on Nether portal destruction Align destination area to [map chunks 5x5x5](https://git.minetest.land/MineClone2/MineClone2/wiki/World-structure%3A-positions%2C-boundaries%2C-blocks%2C-chunks%2C-dimensions%2C-barriers-and-the-void) to avoid lots of ```emerge_area()``` calls Support Nether roof, https://git.minetest.land/MineClone2/MineClone2/issues/1267 Implement better suitable place search, https://git.minetest.land/MineClone2/MineClone2/issues/1126 Implement object queue not to trigger the same search again Avoid lava lakes, https://git.minetest.land/MineClone2/MineClone2/issues/1126 Add ```/spawnstruct nether_portal``` chat command Co-Authored-By: kay27 <kay27@noreply.git.minetest.land> Co-Committed-By: kay27 <kay27@noreply.git.minetest.land>
This commit is contained in:
parent
1f925b6c84
commit
03feb36558
@ -33,25 +33,26 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16)
|
|||||||
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
||||||
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
||||||
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
||||||
local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||||
|
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
||||||
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||||
local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1
|
local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1
|
||||||
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
|
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
|
||||||
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
|
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
|
||||||
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
|
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
|
||||||
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
||||||
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
|
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
|
||||||
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
||||||
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
||||||
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes
|
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes
|
||||||
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes
|
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes
|
||||||
|
|
||||||
local function coordinate_to_block(x)
|
local function coordinate_to_block(x)
|
||||||
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
|
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function coordinate_to_chunk(x)
|
local function coordinate_to_chunk(x)
|
||||||
return math.floor((coordinate_to_block(x) + central_chunk_offset) / mcl_vars.chunksize)
|
return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_vars.pos_to_block(pos)
|
function mcl_vars.pos_to_block(pos)
|
||||||
@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes)
|
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes)
|
||||||
local k_positive_z = k_positive * 2
|
local k_positive_z = k_positive * 2
|
||||||
local k_positive_y = k_positive_z * k_positive_z
|
local k_positive_y = k_positive_z * k_positive_z
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ mcl_worlds = {}
|
|||||||
function mcl_worlds.is_in_void(pos)
|
function mcl_worlds.is_in_void(pos)
|
||||||
local void =
|
local void =
|
||||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||||
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or
|
(pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or
|
||||||
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
||||||
|
|
||||||
local void_deadly = false
|
local void_deadly = false
|
||||||
@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos)
|
|||||||
-- Overworld → Void → End → Void → Nether → Void
|
-- Overworld → Void → End → Void → Nether → Void
|
||||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then
|
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then
|
||||||
-- The void between End and Nether. Like usual, but here, the void
|
-- The void between End and Nether. Like usual, but here, the void
|
||||||
-- *above* the Nether also has a small tolerance area, so player
|
-- *above* the Nether also has a small tolerance area, so player
|
||||||
-- can fly above the Nether without getting hurt instantly.
|
-- can fly above the Nether without getting hurt instantly.
|
||||||
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance)
|
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance)
|
||||||
elseif pos.y < mcl_vars.mg_nether_min then
|
elseif pos.y < mcl_vars.mg_nether_min then
|
||||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||||
end
|
end
|
||||||
@ -35,7 +35,7 @@ end
|
|||||||
function mcl_worlds.y_to_layer(y)
|
function mcl_worlds.y_to_layer(y)
|
||||||
if y >= mcl_vars.mg_overworld_min then
|
if y >= mcl_vars.mg_overworld_min then
|
||||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then
|
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||||
return y - mcl_vars.mg_nether_min, "nether"
|
return y - mcl_vars.mg_nether_min, "nether"
|
||||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||||
return y - mcl_vars.mg_end_min, "end"
|
return y - mcl_vars.mg_end_min, "end"
|
||||||
@ -73,7 +73,7 @@ end
|
|||||||
-- Takes a position and returns true if this position can have Nether dust
|
-- Takes a position and returns true if this position can have Nether dust
|
||||||
function mcl_worlds.has_dust(pos)
|
function mcl_worlds.has_dust(pos)
|
||||||
-- Weather in the Overworld and the high part of the void below
|
-- Weather in the Overworld and the high part of the void below
|
||||||
return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64
|
return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Takes a position (pos) and returns true if compasses are working here
|
-- Takes a position (pos) and returns true if compasses are working here
|
||||||
|
@ -2826,7 +2826,7 @@ local falling = function(self, pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if mcl_portals ~= nil then
|
if mcl_portals ~= nil then
|
||||||
if mcl_portals.nether_portal_cooloff[self.object] then
|
if mcl_portals.nether_portal_cooloff(self.object) then
|
||||||
return false -- mob has teleported through Nether portal - it's 99% not falling
|
return false -- mob has teleported through Nether portal - it's 99% not falling
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
name = mcl_portals
|
name = mcl_portals
|
||||||
description = Adds buildable portals to the Nether and End dimensions.
|
description = Adds buildable portals to the Nether and End dimensions.
|
||||||
depends = mcl_init, mcl_worlds, mcl_core, mcl_nether, mcl_end, mcl_particles, mcl_spawn
|
depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn
|
||||||
optional_depends = awards, doc
|
optional_depends = awards, doc
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ local function add_chunk(pos)
|
|||||||
end
|
end
|
||||||
prev = d
|
prev = d
|
||||||
end
|
end
|
||||||
chunks[#chunks] = {n, n}
|
chunks[#chunks+1] = {n, n}
|
||||||
end
|
end
|
||||||
function mcl_mapgen_core.is_generated(pos)
|
function mcl_mapgen_core.is_generated(pos)
|
||||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||||
@ -1790,6 +1790,8 @@ local generate_nether_decorations = function(minp, maxp, seed)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
||||||
|
|
||||||
-- TODO: Generate everything based on Perlin noise instead of PseudoRandom
|
-- TODO: Generate everything based on Perlin noise instead of PseudoRandom
|
||||||
|
|
||||||
local bpos
|
local bpos
|
||||||
@ -1847,6 +1849,7 @@ local generate_nether_decorations = function(minp, maxp, seed)
|
|||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
|
minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
||||||
add_chunk(minp)
|
add_chunk(minp)
|
||||||
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
||||||
if lvm > 0 then
|
if lvm > 0 then
|
||||||
@ -2132,24 +2135,32 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
|||||||
-- * Replace water with Nether lava.
|
-- * Replace water with Nether lava.
|
||||||
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
||||||
elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then
|
elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then
|
||||||
local nodes
|
|
||||||
if mg_name == "v6" then
|
if mg_name == "v6" then
|
||||||
nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
||||||
else
|
for n=1, #nodes do
|
||||||
nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
|
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
||||||
end
|
if data[p_pos] == c_water then
|
||||||
for n=1, #nodes do
|
data[p_pos] = c_nether_lava
|
||||||
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
lvm_used = true
|
||||||
if data[p_pos] == c_water then
|
elseif data[p_pos] == c_stone then
|
||||||
data[p_pos] = c_nether_lava
|
data[p_pos] = c_netherrack
|
||||||
lvm_used = true
|
lvm_used = true
|
||||||
elseif data[p_pos] == c_stone then
|
elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then
|
||||||
data[p_pos] = c_netherrack
|
data[p_pos] = c_soul_sand
|
||||||
lvm_used = true
|
lvm_used = true
|
||||||
elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then
|
end
|
||||||
data[p_pos] = c_soul_sand
|
|
||||||
lvm_used = true
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param)
|
||||||
|
if calls_remaining > 0 then return end
|
||||||
|
-- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"})
|
||||||
|
local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"})
|
||||||
|
local sn=(mcl_observers and mcl_observers.swap_node) or minetest.swap_node
|
||||||
|
local l = {name="mcl_nether:nether_lava_source"}
|
||||||
|
for _, n in pairs(nodes) do
|
||||||
|
sn(n, l)
|
||||||
|
end
|
||||||
|
end, {minp=vector.new(minp), maxp=vector.new(maxp)})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- End block fixes:
|
-- End block fixes:
|
||||||
|
@ -534,7 +534,7 @@ end
|
|||||||
|
|
||||||
-- Debug command
|
-- Debug command
|
||||||
minetest.register_chatcommand("spawnstruct", {
|
minetest.register_chatcommand("spawnstruct", {
|
||||||
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | dungeon",
|
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | nether_portal | dungeon",
|
||||||
description = S("Generate a pre-defined structure near your position."),
|
description = S("Generate a pre-defined structure near your position."),
|
||||||
privs = {debug = true},
|
privs = {debug = true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
@ -570,6 +570,8 @@ minetest.register_chatcommand("spawnstruct", {
|
|||||||
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
||||||
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
||||||
mcl_dungeons.spawn_dungeon(pos, rot, pr)
|
mcl_dungeons.spawn_dungeon(pos, rot, pr)
|
||||||
|
elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then
|
||||||
|
mcl_portals.spawn_nether_portal(pos, rot, pr, name)
|
||||||
elseif param == "" then
|
elseif param == "" then
|
||||||
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
|
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
|
||||||
errord = true
|
errord = true
|
||||||
|
Loading…
Reference in New Issue
Block a user