mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-25 20:11:06 +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
7 changed files with 598 additions and 569 deletions
|
@ -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.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 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_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 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_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
||||
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 numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / 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_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes
|
||||
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) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
||||
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 * mcl_vars.chunk_size_in_nodes
|
||||
|
||||
local function coordinate_to_block(x)
|
||||
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
function mcl_vars.pos_to_block(pos)
|
||||
|
@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos)
|
|||
}
|
||||
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_y = k_positive_z * k_positive_z
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ mcl_worlds = {}
|
|||
function mcl_worlds.is_in_void(pos)
|
||||
local void =
|
||||
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))
|
||||
|
||||
local void_deadly = false
|
||||
|
@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos)
|
|||
-- Overworld → Void → End → Void → Nether → Void
|
||||
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
|
||||
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
|
||||
-- *above* the Nether also has a small tolerance area, so player
|
||||
-- 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
|
||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||
end
|
||||
|
@ -35,7 +35,7 @@ end
|
|||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
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"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
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
|
||||
function mcl_worlds.has_dust(pos)
|
||||
-- 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
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
|
|
|
@ -2826,7 +2826,7 @@ local falling = function(self, pos)
|
|||
end
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_portals
|
||||
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
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,7 +29,7 @@ local function add_chunk(pos)
|
|||
end
|
||||
prev = d
|
||||
end
|
||||
chunks[#chunks] = {n, n}
|
||||
chunks[#chunks+1] = {n, n}
|
||||
end
|
||||
function mcl_mapgen_core.is_generated(pos)
|
||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||
|
@ -1790,6 +1790,8 @@ local generate_nether_decorations = function(minp, maxp, seed)
|
|||
return
|
||||
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
|
||||
|
||||
local bpos
|
||||
|
@ -1847,6 +1849,7 @@ local generate_nether_decorations = function(minp, maxp, seed)
|
|||
end
|
||||
|
||||
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)
|
||||
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
|
||||
|
@ -2132,12 +2135,8 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
|||
-- * Replace water with Nether lava.
|
||||
-- * 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
|
||||
local nodes
|
||||
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"})
|
||||
else
|
||||
nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source"})
|
||||
end
|
||||
local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
||||
for n=1, #nodes do
|
||||
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
||||
if data[p_pos] == c_water then
|
||||
|
@ -2151,6 +2150,18 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
|||
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 block fixes:
|
||||
-- * Replace water with end stone or air (depending on height).
|
||||
|
|
|
@ -534,7 +534,7 @@ end
|
|||
|
||||
-- Debug command
|
||||
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."),
|
||||
privs = {debug = true},
|
||||
func = function(name, param)
|
||||
|
@ -570,6 +570,8 @@ minetest.register_chatcommand("spawnstruct", {
|
|||
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
||||
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
||||
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
|
||||
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
|
||||
errord = true
|
||||
|
|
Loading…
Reference in a new issue