Fix a bug, remove backward compatibility

This commit is contained in:
Kimapr 2020-01-05 11:34:08 +05:00
parent 32a859db6a
commit 4a17a05296
1 changed files with 61 additions and 115 deletions

View File

@ -33,8 +33,8 @@ local pers = 0.9
local oct = 4 local oct = 4
local noise = PerlinNoise{ local noise = PerlinNoise{
scale = maxval(oct,pers,32), scale = maxval(oct,pers,128),
spread = {x=64,y=64,z=64}, spread = {x=128,y=128,z=128},
seed=1297, seed=1297,
octaves = oct, octaves = oct,
persistence = pers, persistence = pers,
@ -42,6 +42,10 @@ local noise = PerlinNoise{
flags = "eased" flags = "eased"
} }
local function sigmoid(z)
return 1/(1+math.exp(-z))
end
local function island(pos,r,call) local function island(pos,r,call)
local x,y,z = pos.x,pos.y,pos.z local x,y,z = pos.x,pos.y,pos.z
minetest.emerge_area({x=x-r,y=y-r,z=z-r},{x=x+r,y=y+r,z=z+r},function(bp,act,crem) minetest.emerge_area({x=x-r,y=y-r,z=z-r},{x=x+r,y=y+r,z=z+r},function(bp,act,crem)
@ -52,10 +56,10 @@ local function island(pos,r,call)
local c = 0 local c = 0
local cm = (r*2+1)^3 local cm = (r*2+1)^3
local function geto(x1,y1,z1,n) local function geto(x1,y1,z1,n)
local r1 = 48+n*2-1 local r1 = 48+n
local dista = dist(0,0,0,x1,y1*3,z1) local dista = dist(0,0,0,x1,y1*3,z1)
local m = math.max(0,1-dista/r1) local m = math.max(0,1-dista/r1)
local r2 = -r1 local r2 = -(sigmoid((48+n/2)/48*3)*56)
if y1 <= 0 and y1 >= r2 then if y1 <= 0 and y1 >= r2 then
local r3 = (1-math.sin(y1/r2*math.pi/2))*r1 local r3 = (1-math.sin(y1/r2*math.pi/2))*r1
local distb = dist(0,y1,0,x1,y1,z1) local distb = dist(0,y1,0,x1,y1,z1)
@ -130,8 +134,12 @@ local function raw_spawn_island(pos,call)
end end
local function spawn_island(name,pos) local function spawn_island(name,pos)
local ref = minetest.get_player_by_name(name) local ref = minetest.get_player_by_name(name)
raw_spawn_island(pos) raw_spawn_island(pos,function()
ref:set_pos({x=pos.x,y=pos.y+256,z=pos.z}) local ref = minetest.get_player_by_name(name)
if ref then
ref:set_pos({x=pos.x,y=pos.y+64,z=pos.z})
end
end)
end end
local store = minetest.get_mod_storage() local store = minetest.get_mod_storage()
local players = minetest.deserialize(store:get_string("players")) or {} local players = minetest.deserialize(store:get_string("players")) or {}
@ -228,27 +236,33 @@ local function spawn_particles(x,y,z,player)
end end
end end
local function checkpos(x,y,z,ch) local function checkpos(x,y,z,ch)
local mi,ma = islandgen_range(x,y,z) local mi,ma = islandgen_range(f(x),f(y),f(z))
print("requested check for pos "..x.." "..y.." "..z)
minetest.emerge_area(mi,ma,function(bpos,act,crem) minetest.emerge_area(mi,ma,function(bpos,act,crem)
if crem > 0 then if crem > 0 then
return return
end end
print("checking pos "..x.." "..y.." "..z)
local vm = VoxelManip(mi,ma) local vm = VoxelManip(mi,ma)
local emi,ema = vm:get_emerged_area() local emi,ema = vm:get_emerged_area()
local dat = vm:get_data() local dat = vm:get_data()
local ar = VoxelArea:new{MinEdge=emi,MaxEdge=ema} local ar = VoxelArea:new{MinEdge=emi,MaxEdge=ema}
local v = true
for x = mi.x,ma.x do for x = mi.x,ma.x do
for y = mi.y,ma.y do for y = mi.y,ma.y do
for z = mi.y,ma.z do for z = mi.z,ma.z do
local d = dat[ar:index(x,y,z)] local d = dat[ar:index(x,y,z)]
if d ~= air_c and d ~= ignore_c then if d ~= air_c then
ch(false) v = false
return break
end end
end end
if not v then break end
end end
if not v then break end
end end
ch(true) print("running callback; v="..tostring(v))
ch(v)
end) end)
end end
@ -307,7 +321,7 @@ local function gen_island_pos(name,fgen)
return return
end end
local x,y,z = 0,0,0 local x,y,z = 0,0,0
x,z = x+math.random(-96,96),z+math.random(-96,96) x,z = x+math.random(-64,64),z+math.random(-64,64)
y=256+math.random(-32,32) y=256+math.random(-32,32)
if not fgen then if not fgen then
for k,isl in pairs(cells) do for k,isl in pairs(cells) do
@ -319,46 +333,49 @@ local function gen_island_pos(name,fgen)
players[name] = {pos = pos, valid = true} players[name] = {pos = pos, valid = true}
save() save()
pos = {x=f(pos.x),y=f(pos.y),z=f(pos.z)} pos = {x=f(pos.x),y=f(pos.y),z=f(pos.z)}
ref:set_pos({x=pos.x,y=pos.y+256,z=pos.z}) ref:set_pos({x=pos.x,y=pos.y+64,z=pos.z})
return return
end end
end end
end end
local function ch(ok) local function ch(ok)
if not ok then if not ok then
local sx,sz = math.random(-96,96),math.random(-96,96) local sx,sz = math.random(-64,64),math.random(-64,64)
if ((x+sx)^2+(z+sz)^2)^0.5 < (x^2+z^2)^0.5 then if ((x+sx)^2+(z+sz)^2)^0.5 < (x^2+z^2)^0.5 then
sx=-sx sx=-sx
sz=-sz sz=-sz
end end
x,z = x+sx,z+sz x,z = x+sx,z+sz
y=256+math.random(-32,32) y=256+math.random(-32,32)
ok = checkpos(x,y,z,ch) checkpos(x,y,z,ch)
else else
local ip = {x=x,y=y,z=z} local ip = {x=x,y=y,z=z}
if not fgen then checkpos(x,y,z,function(ok)
spawn_island(name,ip) assert(ok,"super-duper-error")
else if not fgen then
raw_spawn_island(ip,function() spawn_island(name,ip)
ended = ended + 1 else
if ended >= (fgen or 1) then raw_spawn_island(ip,function()
minetest.chat_send_player(name,S"Island generation done") ended = ended + 1
else if ended >= (fgen or 1) then
minetest.chat_send_player(name,S("Generated an island (@1%)"), math.floor(ended/(fgen or 1)*1000)/10) minetest.chat_send_player(name,S"Island generation done")
end else
minetest.after(0,gen,n+1) minetest.chat_send_player(name,S("Generated an island (@1%)", math.floor(ended/(fgen or 1)*1000)/10))
end) end
end gen(n+1)
local pl = { end)
pos = ip, end
valid = true local pl = {
} pos = ip,
if not fgen then valid = true
players[name] = pl }
else if not fgen then
table.insert(cells,pl) players[name] = pl
end else
save() table.insert(cells,pl)
end
save()
end)
end end
end end
checkpos(x,y,z,ch) checkpos(x,y,z,ch)
@ -380,7 +397,7 @@ minetest.register_globalstep(function(dt)
to_upd = to_upd+updrate to_upd = to_upd+updrate
for k,ref in pairs(minetest.get_connected_players()) do for k,ref in pairs(minetest.get_connected_players()) do
local is = get_standing_island(ref:get_player_name()) local is = get_standing_island(ref:get_player_name())
if is and is.t == cells and not minetest.check_player_privs(ref,{server = true}) then if is and not minetest.check_player_privs(ref,{server = true}) then
cells[is.k].valid = false cells[is.k].valid = false
end end
local p = ref:get_pos() local p = ref:get_pos()
@ -395,7 +412,7 @@ minetest.register_globalstep(function(dt)
gen_island_pos(ref:get_player_name()) gen_island_pos(ref:get_player_name())
end end
if pos then if pos then
pos.y=pos.y+256 pos.y=pos.y+64
ref:set_pos(pos) ref:set_pos(pos)
end end
end end
@ -575,78 +592,7 @@ minetest.register_chatcommand("islandgen",{
minetest.register_on_joinplayer(function(ref) minetest.register_on_joinplayer(function(ref)
local meta = ref:get_meta() local meta = ref:get_meta()
local name = ref:get_player_name() local name = ref:get_player_name()
if meta:get_string("islandpos") ~= "" then if not players[name] then
if not players[name] then gen_island_pos(name)
local pos = minetest.string_to_pos(meta:get_string("islandpos"))
local hascell = false
for k,v in pairs(players) do
if vector.length(vector.subtract(v.pos,pos)) < 8 then
hascell = true
break
end
end
while true do
local rem = false
for k,v in pairs(cells) do
if vector.length(vector.subtract(v.pos,pos)) < 8 then
table.remove(cells,k)
rem = true
break
end
end
if not rem then
break
end
end
if not hascell then
local pl = {
pos = pos,
valid = false
}
players[name] = pl
else
gen_island_pos(name)
end
end
save()
meta:set_string("island","")
meta:set_string("islandpos","")
meta:set_string("islandrange","")
else
if not players[name] then
gen_island_pos(name)
save()
else
local p = players[name]
if p.islandpos then
players[name] = {pos = p.islandpos, valid = false}
save()
end
local pos = players[name].pos
local hascell = false
for k,v in pairs(players) do
if vector.length(vector.subtract(v.pos,pos)) < 8 and k ~= name then
hascell = true
break
end
end
while true do
local rem = false
for k,v in pairs(cells) do
if vector.length(vector.subtract(v.pos,pos)) < 8 then
table.remove(cells,k)
rem = true
break
end
end
if not rem then
break
end
end
if hascell then
players[name] = nil
gen_island_pos(name)
end
end
end end
end) end)