forked from Minetest/dynamic_liquid
Combine mapgen callbacks for efficiency (#7)
1. Two read/write pairs to the VM have been replaced with one. 2. If no changes are made to the data, it is not written back to the VM.mineclone_compatibility
parent
186d8743b4
commit
cf67547455
86
init.lua
86
init.lua
|
@ -320,29 +320,7 @@ if not springs then
|
||||||
end
|
end
|
||||||
minetest.register_node("dynamic_liquid:clay", clay_def)
|
minetest.register_node("dynamic_liquid:clay", clay_def)
|
||||||
|
|
||||||
local data = {}
|
|
||||||
|
|
||||||
if springs then
|
if springs then
|
||||||
local c_clay = minetest.get_content_id("default:clay")
|
|
||||||
local c_spring_clay = minetest.get_content_id("dynamic_liquid:clay")
|
|
||||||
|
|
||||||
-- Turn mapgen clay into spring clay
|
|
||||||
minetest.register_on_generated(function(minp, maxp, seed)
|
|
||||||
if minp.y >= water_level or maxp.y <= -15 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
||||||
vm:get_data(data)
|
|
||||||
|
|
||||||
for voxelpos, voxeldata in pairs(data) do
|
|
||||||
if voxeldata == c_clay then
|
|
||||||
data[voxelpos] = c_spring_clay
|
|
||||||
end
|
|
||||||
end
|
|
||||||
vm:set_data(data)
|
|
||||||
vm:write_to_map()
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "dynamic_liquid damp clay spring",
|
label = "dynamic_liquid damp clay spring",
|
||||||
nodenames = {"dynamic_liquid:clay"},
|
nodenames = {"dynamic_liquid:clay"},
|
||||||
|
@ -409,34 +387,38 @@ end
|
||||||
|
|
||||||
local mapgen_prefill = minetest.settings:get_bool("dynamic_liquid_mapgen_prefill", true)
|
local mapgen_prefill = minetest.settings:get_bool("dynamic_liquid_mapgen_prefill", true)
|
||||||
|
|
||||||
local waternodes
|
if springs or mapgen_prefill then
|
||||||
|
local data = {}
|
||||||
|
|
||||||
if mapgen_prefill then
|
local c_clay = minetest.get_content_id("default:clay")
|
||||||
|
local c_spring_clay = minetest.get_content_id("dynamic_liquid:clay")
|
||||||
local c_water = minetest.get_content_id("default:water_source")
|
local c_water = minetest.get_content_id("default:water_source")
|
||||||
local c_air = minetest.get_content_id("air")
|
local c_air = minetest.get_content_id("air")
|
||||||
waternodes = {}
|
local waternodes = {}
|
||||||
|
|
||||||
local fill_to = function (vi, data, area)
|
local fill_to = function (vi, data, area)
|
||||||
if area:containsi(vi) and area:position(vi).y <= water_level then
|
if area:containsi(vi) and area:position(vi).y <= water_level then
|
||||||
if data[vi] == c_air then
|
if data[vi] == c_air then
|
||||||
data[vi] = c_water
|
data[vi] = c_water
|
||||||
table.insert(waternodes, vi)
|
table.insert(waternodes, vi)
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- local count = 0
|
-- local count = 0
|
||||||
local drop_liquid = function(vi, data, area, min_y)
|
local drop_liquid = function(vi, data, area, min_y)
|
||||||
if data[vi] ~= c_water then
|
if data[vi] ~= c_water then
|
||||||
-- we only care about water.
|
-- we only care about water.
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
local start = vi -- remember the water node we started from
|
local start = vi -- remember the water node we started from
|
||||||
local ystride = area.ystride
|
local ystride = area.ystride
|
||||||
vi = vi - ystride
|
vi = vi - ystride
|
||||||
if data[vi] ~= c_air then
|
if data[vi] ~= c_air then
|
||||||
-- if there's no air below this water node, give up immediately.
|
-- if there's no air below this water node, give up immediately.
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
vi = vi - ystride -- There's air below the water, so move down one.
|
vi = vi - ystride -- There's air below the water, so move down one.
|
||||||
while data[vi] == c_air and area:position(vi).y > min_y do
|
while data[vi] == c_air and area:position(vi).y > min_y do
|
||||||
|
@ -452,19 +434,34 @@ if mapgen_prefill then
|
||||||
-- if count % 100 == 0 then
|
-- if count % 100 == 0 then
|
||||||
-- minetest.chat_send_all("dropped water " .. (start-vi)/ystride .. " at " .. minetest.pos_to_string(area:position(vi)))
|
-- minetest.chat_send_all("dropped water " .. (start-vi)/ystride .. " at " .. minetest.pos_to_string(area:position(vi)))
|
||||||
-- end
|
-- end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp, seed)
|
minetest.register_on_generated(function(minp, maxp, seed)
|
||||||
if minp.y > water_level then
|
|
||||||
-- we're in the sky.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
||||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
||||||
vm:get_data(data)
|
|
||||||
local maxp_y = maxp.y
|
local maxp_y = maxp.y
|
||||||
local minp_y = minp.y
|
local minp_y = minp.y
|
||||||
|
local vm, emin, emax
|
||||||
|
local dirty = false
|
||||||
|
local update_liquids = false
|
||||||
|
|
||||||
|
if springs and minp_y < water_level and maxp_y > -15 then
|
||||||
|
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
|
vm:get_data(data)
|
||||||
|
|
||||||
|
for voxelpos = 1, #data do
|
||||||
|
if data[voxelpos] == c_clay then
|
||||||
|
data[voxelpos] = c_spring_clay
|
||||||
|
dirty = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if mapgen_prefill and minp_y <= water_level then
|
||||||
|
if not vm then
|
||||||
|
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
|
vm:get_data(data)
|
||||||
|
end
|
||||||
|
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||||
|
|
||||||
if maxp_y > -70 then
|
if maxp_y > -70 then
|
||||||
local top = vector.new(maxp.x, math.min(maxp_y, water_level), maxp.z) -- prevents flood fill from affecting any water above sea level
|
local top = vector.new(maxp.x, math.min(maxp_y, water_level), maxp.z) -- prevents flood fill from affecting any water above sea level
|
||||||
|
@ -482,11 +479,11 @@ if mapgen_prefill then
|
||||||
local front = vi - 1
|
local front = vi - 1
|
||||||
local back = vi + 1
|
local back = vi + 1
|
||||||
|
|
||||||
fill_to(below, data, area)
|
dirty = fill_to(below, data, area) or dirty
|
||||||
fill_to(left, data, area)
|
dirty = fill_to(left, data, area) or dirty
|
||||||
fill_to(right, data, area)
|
dirty = fill_to(right, data, area) or dirty
|
||||||
fill_to(front, data, area)
|
dirty = fill_to(front, data, area) or dirty
|
||||||
fill_to(back, data, area)
|
dirty = fill_to(back, data, area) or dirty
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Caves sometimes generate with liquid nodes hovering in mid air.
|
-- Caves sometimes generate with liquid nodes hovering in mid air.
|
||||||
|
@ -497,13 +494,20 @@ if mapgen_prefill then
|
||||||
-- We could possibly be a bit more efficient by remembering how far we dropped then
|
-- We could possibly be a bit more efficient by remembering how far we dropped then
|
||||||
-- last liquid node in a column and moving stuff down that far,
|
-- last liquid node in a column and moving stuff down that far,
|
||||||
-- but for now let's keep it simple.
|
-- but for now let's keep it simple.
|
||||||
drop_liquid(vi, data, area, minp_y)
|
dirty = drop_liquid(vi, data, area, minp_y) or dirty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
update_liquids = dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
if dirty then
|
||||||
vm:set_data(data)
|
vm:set_data(data)
|
||||||
vm:write_to_map()
|
vm:write_to_map()
|
||||||
|
if update_liquids then
|
||||||
vm:update_liquids()
|
vm:update_liquids()
|
||||||
|
end
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue