Use AreaStore
parent
38fe40c49c
commit
f64ecdf764
18
README.md
18
README.md
|
@ -5,3 +5,21 @@ Adds environmental sounds to Minetest
|
|||
Created by rubenwardy.
|
||||
|
||||
License: LGPL 2.1 or later.
|
||||
|
||||
# Work in Progress
|
||||
|
||||
This project is a Work in Progress
|
||||
|
||||
* environment.expand_fill(cid, px, py, pz, max_radius)
|
||||
* Combines multiple nodes of the same type into a cubic AreaStore entry.
|
||||
* Good for large surfaces of water.
|
||||
* TODO:
|
||||
* Check for collisions with existing stores.
|
||||
* environment.scan_around_player(name)
|
||||
* Scans for sound sources and plays them.
|
||||
* TODO:
|
||||
* don't just play sounds for the center of an area,
|
||||
play from edge if outside.
|
||||
* water sounds should come from surface.
|
||||
* TODO:
|
||||
* run environment.expand_fill on mapgen somehow.
|
||||
|
|
315
init.lua
315
init.lua
|
@ -8,6 +8,7 @@
|
|||
|
||||
]]
|
||||
|
||||
local areas = AreaStore()
|
||||
environment = {
|
||||
_nodes = {}
|
||||
}
|
||||
|
@ -48,32 +49,169 @@ function environment.register_node_with_sounds(name, spec)
|
|||
return environment.register_node(name)
|
||||
end
|
||||
|
||||
minetest.register_node("environment:test",{
|
||||
--[[minetest.register_node("environment:test", {
|
||||
tiles = {"default_stone.png"},
|
||||
sounds = {
|
||||
presence = {name="small_waterfall"}
|
||||
}
|
||||
})
|
||||
environment.register_node("environment:test")
|
||||
environment.register_node("environment:test")]]
|
||||
|
||||
--[[environment.register_node_with_sounds("default:water_source", {
|
||||
environment.register_node_with_sounds("default:water_source", {
|
||||
presence = {name="small_waterfall"}
|
||||
})]]
|
||||
})
|
||||
|
||||
local SCAN_RANGE = 32
|
||||
local MAX_SOURCES = 16
|
||||
function environment.scan_around_player(name)
|
||||
-- Small Optimisations
|
||||
function environment.expand_fill(cid, px, py, pz, max_radius)
|
||||
print("Scanning from " .. minetest.pos_to_string({
|
||||
x=px, y=py, z=pz
|
||||
}) .. " looking for ID " .. cid .. " with max_radius " .. max_radius)
|
||||
|
||||
-- Initiate areas
|
||||
local watch_nodes = environment._nodes
|
||||
local minp = {
|
||||
x = px - max_radius,
|
||||
y = py - max_radius,
|
||||
z = pz - max_radius
|
||||
}
|
||||
local maxp = {
|
||||
x = px + max_radius,
|
||||
y = py + max_radius,
|
||||
z = pz + max_radius
|
||||
}
|
||||
local ax, bx = px, px
|
||||
local ay, by = py, py
|
||||
local az, bz = pz, pz
|
||||
|
||||
-- Get player
|
||||
-- Set up voxel manip
|
||||
local vm = minetest.get_voxel_manip()
|
||||
minp, maxp = vm:read_from_map(minp, maxp)
|
||||
local a = VoxelArea:new{MinEdge = minp, MaxEdge = maxp}
|
||||
local data = vm:get_data()
|
||||
|
||||
-- Expand cuboid
|
||||
local c2 = 0, 0
|
||||
local function expand()
|
||||
local top_fine = true
|
||||
local bottom_fine = true
|
||||
|
||||
-- Front and back faces
|
||||
local front_fine = true
|
||||
local back_fine = true
|
||||
for x = ax, bx do
|
||||
for y = ay, by do
|
||||
if front_fine then
|
||||
local vi = a:index(x, y, az - 1)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
front_fine = false
|
||||
end
|
||||
end
|
||||
|
||||
if back_fine then
|
||||
local vi = a:index(x, y, bz + 1)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
back_fine = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if front_fine then
|
||||
az = az - 1
|
||||
--print("Expanded one.z to " .. az)
|
||||
end
|
||||
if back_fine then
|
||||
bz = bz + 1
|
||||
--print("Expanded two.z to " .. bz)
|
||||
end
|
||||
|
||||
-- Left and right faces
|
||||
local left_fine = true
|
||||
local right_fine = true
|
||||
for z = az, bz do
|
||||
for y = ay, by do
|
||||
if left_fine then
|
||||
local vi = a:index(ax - 1, y, z)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
left_fine = false
|
||||
end
|
||||
end
|
||||
|
||||
if right_fine then
|
||||
local vi = a:index(bx + 1, y, z)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
right_fine = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if left_fine then
|
||||
ax = ax - 1
|
||||
--print("Expanded one.x to " .. ax)
|
||||
end
|
||||
if right_fine then
|
||||
bx = bx + 1
|
||||
--print("Expanded two.x to " .. bx)
|
||||
end
|
||||
|
||||
-- Top and bottom faces
|
||||
local top_fine = true
|
||||
local bottom_fine = true
|
||||
for x = az, bz do
|
||||
for z = ay, by do
|
||||
if top_fine then
|
||||
local vi = a:index(x, ay - 1, z)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
top_fine = false
|
||||
end
|
||||
end
|
||||
|
||||
if bottom_fine then
|
||||
local vi = a:index(x, by + 1, z)
|
||||
c2 = c2 + 1
|
||||
if data[vi] ~= cid then
|
||||
bottom_fine = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if top_fine then
|
||||
ay = ay - 1
|
||||
--print("Expanded one.y to " .. ay)
|
||||
end
|
||||
if bottom_fine then
|
||||
by = by + 1
|
||||
--print("Expanded two.y to " .. by)
|
||||
end
|
||||
|
||||
return front_fine or back_fine or left_fine or right_fine
|
||||
end
|
||||
|
||||
for i = 1, max_radius do
|
||||
--print("- iteration " .. i)
|
||||
if not expand() then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local a = {x=ax, y=ay, z=az}
|
||||
local b = {x=bx, y=by, z=bz}
|
||||
print(minetest.pos_to_string(a) .. " to " .. minetest.pos_to_string(b))
|
||||
print("Checked " .. c2 .. " nodes.")
|
||||
|
||||
-- Insert into AreaStore
|
||||
areas:insert_area(a, b, cid)
|
||||
end
|
||||
|
||||
function environment.scan_around_player(name)
|
||||
local watch_nodes = environment._nodes
|
||||
local player = minetest.get_player_by_name(name)
|
||||
print("Starting scan...")
|
||||
|
||||
-- Get range
|
||||
local pos = player:getpos()
|
||||
pos = vector.round(pos)
|
||||
local px, py, pz = pos.x, pos.y, pos.z
|
||||
local minp = {
|
||||
x = pos.x - SCAN_RANGE,
|
||||
y = pos.y - SCAN_RANGE,
|
||||
|
@ -85,142 +223,35 @@ function environment.scan_around_player(name)
|
|||
z = pos.z + SCAN_RANGE
|
||||
}
|
||||
|
||||
-- Set up voxel manip
|
||||
local vm = minetest.get_voxel_manip()
|
||||
minp, maxp = vm:read_from_map(minp, maxp)
|
||||
local a = VoxelArea:new{
|
||||
MinEdge = minp,
|
||||
MaxEdge = maxp
|
||||
}
|
||||
local data = vm:get_data()
|
||||
local arealist = areas:get_areas_in_area(minp, maxp, true, true, true)
|
||||
for i, area in pairs(arealist) do
|
||||
local source = {
|
||||
x = (area.min.x + area.max.x) / 2,
|
||||
y = (area.min.y + area.max.y) / 2,
|
||||
z = (area.min.z + area.max.z) / 2
|
||||
}
|
||||
local def = watch_nodes[math.floor(tonumber(area.data))]
|
||||
|
||||
-- Loop through
|
||||
local count = 0
|
||||
local radius = 1
|
||||
local c2 = 0
|
||||
print("Adding source to " .. minetest.pos_to_string(source))
|
||||
local handle = minetest.sound_play(def.presence, {
|
||||
pos = source,
|
||||
gain = def.presence.gain,
|
||||
max_hear_distance = SCAN_RANGE
|
||||
})
|
||||
|
||||
(function()
|
||||
local function handle_source(def, x, y, z)
|
||||
print("Adding source to (" .. x .. ", " .. y .. ", " .. z .. ")")
|
||||
minetest.sound_play(def.presence, {
|
||||
pos = {x=x, y=y, z=z},
|
||||
gain = def.presence.gain,
|
||||
max_hear_distance = SCAN_RANGE
|
||||
})
|
||||
if i > 16 then
|
||||
print("Bigger than 16!")
|
||||
break
|
||||
end
|
||||
|
||||
-- Check center
|
||||
--[[local vi = a:index(px, py, pz)
|
||||
local def = watch_nodes[data[vi] ]
|
||||
if def then
|
||||
handle_source(def, px, py, pz)
|
||||
count = count + 1
|
||||
end
|
||||
c2 = c2 + 1]]
|
||||
|
||||
print("Scanning from " .. minetest.pos_to_string(pos) .. " with range " .. SCAN_RANGE)
|
||||
|
||||
while radius < SCAN_RANGE do
|
||||
print(" - radius " .. radius)
|
||||
|
||||
-- Front and back faces
|
||||
for x = -radius, radius do
|
||||
for y = -radius, radius do
|
||||
local vi = a:index(px + x, py + y, pz + radius)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px + x, py + y, pz + radius)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 1
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local vi = a:index(px + x, py + y, pz - radius)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px + x, py + y, pz - radius)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 2
|
||||
return
|
||||
end
|
||||
end
|
||||
c2 = c2 + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Left and right
|
||||
for z = -radius, radius do
|
||||
for y = -radius, radius do
|
||||
local vi = a:index(px + radius, py + y, pz + z)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px + radius, py + y, pz + z)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 1
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local vi = a:index(px - radius, py + y, pz + z)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px - radius, py + y, pz + z)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 2
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
c2 = c2 + 2
|
||||
end
|
||||
end
|
||||
|
||||
-- Top and bottom
|
||||
for x = -radius, radius do
|
||||
for z = -radius, radius do
|
||||
local vi = a:index(px + x, py + radius, pz + z)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px + x, py + radius, pz + z)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 1
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local vi = a:index(px + x, py - radius, pz + z)
|
||||
local def = watch_nodes[data[vi]]
|
||||
if def then
|
||||
handle_source(def, px + x, py - radius, pz + z)
|
||||
count = count + 1
|
||||
if count >= MAX_SOURCES then
|
||||
c2 = c2 + 2
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
c2 = c2 + 2
|
||||
end
|
||||
end
|
||||
|
||||
radius = radius + 1
|
||||
end
|
||||
end)()
|
||||
|
||||
print("End of scan. Found " .. count .. " sources out of " .. c2 .. " nodes.")
|
||||
|
||||
local err = radius * radius * radius - c2
|
||||
if err > 0 then
|
||||
print("Error! Missing " .. err .. " nodes!")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("e", {
|
||||
func = function(name)
|
||||
environment.expand_fill(minetest.get_content_id("default:water_source"), 0, 0, 0, 20)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("s", {
|
||||
func = environment.scan_around_player
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue