tibia-rme/scripts/river_generator.lua
Eduardo Dantas ea6b515552
ci: rework build workflows and vcpkg baseline (#176)
New Features:
- Docker support: new container build and .dockerignore to reduce build-context size.
- Automated vcpkg baseline updater.

CI/CD Improvements:
- Introduces consolidated reusable CI with platform build and Docker workflows.
- Adds cache-cleanup and autofix/format workflows; removes several legacy platform-specific CI files.

Chores:
- Reorganized CMake presets and build configuration; updated build scripts and project metadata.

Style:
- Large-scale formatting/whitespace normalization across many scripts and build files.
2026-05-01 19:45:45 -03:00

181 lines
3.2 KiB
Lua

-- @Title: River Generator
-- @Description: Generates a river using Bezier curves
-- @Author: VLL Systems
-- @Version: 1.0.0
if not app.hasMap() then
print("[River] No map open.")
return
end
local dlg = Dialog({
title = "River Generator",
width = 400,
})
dlg:label({
text = "Generate a river using Bezier curves.",
})
dlg:separator()
dlg:label({
text = "Start Point:",
})
dlg:number({
id = "x1",
label = "X:",
value = 1000,
min = 1,
max = 65000,
})
dlg:number({
id = "y1",
label = "Y:",
value = 1000,
min = 1,
max = 65000,
})
dlg:newrow()
dlg:label({
text = "Control Point (curve):",
})
dlg:number({
id = "mx",
label = "X:",
value = 1015,
min = 1,
max = 65000,
})
dlg:number({
id = "my",
label = "Y:",
value = 1005,
min = 1,
max = 65000,
})
dlg:newrow()
dlg:label({
text = "End Point:",
})
dlg:number({
id = "x2",
label = "X:",
value = 1030,
min = 1,
max = 65000,
})
dlg:number({
id = "y2",
label = "Y:",
value = 1015,
min = 1,
max = 65000,
})
dlg:newrow()
dlg:number({
id = "cz",
label = "Floor Z:",
value = 7,
min = 0,
max = 15,
})
dlg:number({
id = "riverWidth",
label = "River Width:",
value = 3,
min = 1,
max = 10,
})
dlg:number({
id = "steps",
label = "Curve Steps:",
value = 60,
min = 10,
max = 200,
})
dlg:newrow()
dlg:input({
id = "waterBrush",
label = "Water Brush:",
text = "sea",
})
dlg:newrow()
dlg:separator()
dlg:button({
id = "go",
text = "Generate River",
focus = true,
onclick = function(d)
d:close()
end,
})
dlg:show()
local data = dlg.data
local cz = math.floor(data.cz)
local riverWidth = math.floor(data.riverWidth)
local steps = math.floor(data.steps)
local waterBrush = data.waterBrush
local controlPoints = {
{
x = math.floor(data.x1),
y = math.floor(data.y1),
},
{
x = math.floor(data.mx),
y = math.floor(data.my),
},
{
x = math.floor(data.x2),
y = math.floor(data.y2),
},
}
local curvePoints = geo.bezierCurve(controlPoints, steps)
print(string.format("[River] Drawing river with %d curve points, width %d...", #curvePoints, riverWidth))
local map = app.map
local count = 0
local half = math.floor(riverWidth / 2)
app.transaction("Generate River", function()
local painted = {}
for _, pt in ipairs(curvePoints) do
for dy = -half, half do
for dx = -half, half do
local dist = math.sqrt(dx * dx + dy * dy)
if dist <= half + 0.5 then
local x = math.floor(pt.x) + dx
local y = math.floor(pt.y) + dy
local key = x .. "," .. y
if not painted[key] then
painted[key] = true
local tile = map:getOrCreateTile(x, y, cz)
if tile then
tile:applyBrush(waterBrush, false)
count = count + 1
end
end
end
end
end
end
-- Borderize
local minX = math.min(data.x1, data.x2, data.mx) - half - 3
local maxX = math.max(data.x1, data.x2, data.mx) + half + 3
local minY = math.min(data.y1, data.y2, data.my) - half - 3
local maxY = math.max(data.y1, data.y2, data.my) + half + 3
for y = minY, maxY do
for x = minX, maxX do
local tile = map:getOrCreateTile(x, y, cz)
if tile then
tile:borderize()
end
end
end
end)
local midX = math.floor((data.x1 + data.x2) / 2)
local midY = math.floor((data.y1 + data.y2) / 2)
app.setCameraPosition(midX, midY, cz)
print(string.format("[River] Done! %d water tiles placed.", count))