waterbot: add WIP water renewing bot
At the moment it can just give you a list of water sources that can be bucketed without having a net loss of water. Next is to make an automatic bucket filler hack using that.
This commit is contained in:
parent
6c73180988
commit
0febd39537
@ -42,3 +42,4 @@ load_mod_muse = true
|
||||
load_mod_optimize = true
|
||||
load_mod_render = true
|
||||
load_mod_combat = true
|
||||
load_mod_waterbot = true
|
||||
|
106
clientmods/waterbot/init.lua
Normal file
106
clientmods/waterbot/init.lua
Normal file
@ -0,0 +1,106 @@
|
||||
-- CC0/Unlicense Emilia 2020
|
||||
waterbot = {}
|
||||
|
||||
-- Lua doesnt have enums and tables look gross
|
||||
-- should still be a table tho
|
||||
local WATER_USABLE = 0 -- water source
|
||||
local WATER_STABLE = 1 -- water source used for refreshing other sources
|
||||
local WATER_USED = 2 -- water source that can be bucketed
|
||||
local AIR = 3 -- something that water can flow into and renew
|
||||
local SOLID = 4 -- something that water cannot flow into and renew
|
||||
|
||||
local function get_offset(pos, radius)
|
||||
return vector.round({
|
||||
x = pos.x - radius - 1,
|
||||
y = pos.y - radius - 1,
|
||||
z = pos.z - radius - 1
|
||||
})
|
||||
end
|
||||
|
||||
-- returns {{{n n n} {n n n} ...} {...} ...}
|
||||
local function get_intarr(pos, radius)
|
||||
local offset = get_offset(pos, radius)
|
||||
local out = {}
|
||||
local diameter = radius * 2 + 1
|
||||
|
||||
for z = 1, diameter do
|
||||
table.insert(out, {})
|
||||
for y = 1, diameter do
|
||||
table.insert(out[#out], {})
|
||||
for x = 1, diameter do
|
||||
local npos = {x = x, y = y, z = z}
|
||||
local node = minetest.get_node_or_nil(vector.add(offset, npos))
|
||||
local v = SOLID
|
||||
if node then
|
||||
if node.name == "mcl_core:water_source" then
|
||||
v = WATER_USABLE
|
||||
elseif node.name == "air" then
|
||||
v = AIR
|
||||
end
|
||||
end
|
||||
table.insert(out[#out][#out[#out]], v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return out
|
||||
end
|
||||
|
||||
local function coord_valid(coord, width, height)
|
||||
return ((coord[1] > 0) and (coord[2] > 0)) and ((coord[1] <= width) and (coord[2] <= height))
|
||||
end
|
||||
|
||||
-- returns modified list and safe sources
|
||||
-- table is [z][y][x] accessed
|
||||
-- safe sources is a coordinate list
|
||||
-- this is like cellular automata but the state is mogrified in place
|
||||
local function mogrify_stable(t, offset)
|
||||
local safe = {}
|
||||
|
||||
-- indented like this because this is necessary and full indent would be ugly
|
||||
for zi, zv in ipairs(t) do
|
||||
for yi, yv in ipairs(zv) do
|
||||
for xi, xv in ipairs(yv) do
|
||||
if xv == WATER_USABLE then
|
||||
local nhood = {
|
||||
{xi - 1, zi},
|
||||
{xi, zi - 1},
|
||||
{xi + 1, zi},
|
||||
{xi, zi + 1}
|
||||
}
|
||||
|
||||
local last
|
||||
local applied = false
|
||||
|
||||
for i, v in ipairs(nhood) do
|
||||
if not applied and coord_valid(v, #yv, #t) then
|
||||
local check = t[v[2]][yi][v[1]]
|
||||
if check == WATER_USABLE or check == WATER_STABLE then
|
||||
if not last then
|
||||
last = v
|
||||
else
|
||||
t[ v[2]][yi][ v[1]] = WATER_STABLE
|
||||
t[last[2]][yi][last[1]] = WATER_STABLE
|
||||
yv[xi] = WATER_USED
|
||||
table.insert(safe,
|
||||
vector.add(offset,
|
||||
{x = xi, y = yi, z = zi}))
|
||||
applied = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return t, safe
|
||||
end
|
||||
|
||||
function waterbot.find_renewable_water_near(pos, radius)
|
||||
local int = get_intarr(pos, radius)
|
||||
local offset = get_offset(pos, radius)
|
||||
local mint, safe = mogrify_stable(int, offset)
|
||||
return safe
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user