-- 柏林噪声函数by<a>ink芯<a>
local function interpolate(a, b, t)
return a + t * (b - a)
end
local function randomGradient(x, y)
local hash = (x * 12345 + y * 67890) % 10000
local angle = (hash / 10000) * 2 * math.pi
return math.cos(angle), math.sin(angle)
end
local function dotGradient(ix, iy, x, y)
local dx = x - ix
local dy = y - iy
local gx, gy = randomGradient(ix, iy)
return dx * gx + dy * gy
end
-- 2D柏林噪声函数
local function perlinNoise(x, y)
local ix = math.floor(x)
local iy = math.floor(y)
local fx = x - ix
local fy = y - iy
local u = fx * fx * fx * (fx * (fx * 6 - 15) + 10)
local v = fy * fy * fy * (fy * (fy * 6 - 15) + 10)
local n0 = dotGradient(ix, iy, x, y)
local n1 = dotGradient(ix + 1, iy, x, y)
local n2 = dotGradient(ix, iy + 1, x, y)
local n3 = dotGradient(ix + 1, iy + 1, x, y)
local x1 = interpolate(n0, n1, u)
local x2 = interpolate(n2, n3, u)
return interpolate(x1, x2, v)
end
-- 分形布朗运动(多倍频噪声叠加)
local function fbm(x, y, octaves, persistence, lacunarity)
local total = 0
local amplitude = 1
local frequency = 1
local maxValue = 0
for i = 1, octaves do
total = total + perlinNoise(x * frequency, y * frequency) * amplitude
maxValue = maxValue + amplitude
amplitude = amplitude * persistence
frequency = frequency * lacunarity
end
return total / maxValue -- 归一化到[-1,1]
end
-- 地形生成主函数(移除水方块,替换为泥土)
local function generateTerrain(playerObjid)
-- 获取玩家当前位置
local _, px, py, pz = Player:getPosition(playerObjid)
px = math.floor(px)
pz = math.floor(pz)
local baseY = math.floor(py) -- 地形基准高度
Chat:sendSystemMsg("正在生成无水域柏林噪声地形...")
-- 生成31x31范围地形(中心在玩家位置)
local range = 15
for x = -range, range do
for z = -range, range do
-- 计算噪声值(4倍频,提升细节)
local noise = fbm((px + x) / 20, (pz + z) / 20, 4, 0.5, 2.0)
-- 映射噪声值到地形高度(-1→baseY-3,1→baseY+5)
local terrainY = baseY + math.floor(noise * 4 + 1)
-- 放置方块(移除水方块,低地改为泥土)
if terrainY >= baseY + 3 then
-- 高山:石头(ID:104)
Block:setBlockAll(px + x, terrainY, pz + z, 104, 0)
-- 山底:基岩(ID:1)
Block:setBlockAll(px + x, terrainY - 1, pz + z, 1, 0)
elseif terrainY >= baseY then
-- 平地:草块(ID:2)
Block:setBlockAll(px + x, terrainY, pz + z, 2, 0)
-- 地下:泥土(ID:101)
for dy = 1, 2 do
Block:setBlockAll(px + x, terrainY - dy, pz + z, 101, 0)
end
else
-- 低地:泥土(替换原水方块,ID:101)
Block:setBlockAll(px + x, terrainY, pz + z, 101, 0)
-- 地下:1层泥土地基
Block:setBlockAll(px + x, terrainY - 1, pz + z, 101, 0)
end
end
end
Chat:sendSystemMsg("无水域地形生成完成!范围:" .. (range * 2 + 1) .. "x" .. (range * 2 + 1))
end
-- 监听玩家使用道具事件
local function onPlayerUseItem(event)
local itemid = event.itemid
local playerObjid = event.eventobjid
-- 仅当使用石剑(ID:12012)时触发
if itemid == 12012 then
generateTerrain(playerObjid)
end
end
-- 注册事件
ScriptSupportEvent:registerEvent([=[Player.UseItem]=], onPlayerUseItem)迷你世界脚本2.0