Compare commits
2 Commits
feature-re
...
feature-sm
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dd3ddd35c | |||
| f926fdc493 |
136
api.lua
136
api.lua
@@ -105,61 +105,103 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--Overwrite source
|
--Overwrite source
|
||||||
source_liquid_def.liquid_range = 0
|
-- source_liquid_def.liquid_range = 0
|
||||||
source_liquid_def.groups.liquid_physics = 1
|
source_liquid_def.groups.liquid_physics = 1
|
||||||
|
|
||||||
core.register_node(":" .. source_liquid_name, source_liquid_def)
|
-- core.register_node(":" .. source_liquid_name, {
|
||||||
|
-- description = source_liquid_def.description,
|
||||||
|
-- paramtype2 = "flowingliquid",
|
||||||
|
|
||||||
|
-- drawtype = "flowingliquid", -- Used by drawtype = "flowingliquid"
|
||||||
|
-- liquidtype = "", -- Flowing not needed here since condition is already met?
|
||||||
|
|
||||||
|
-- tiles = source_liquid_def.tiles, -- As needed by drawtype - copy from water
|
||||||
|
-- special_tiles = source_liquid_def.tiles,
|
||||||
|
-- use_texture_alpha = true,
|
||||||
|
|
||||||
|
-- liquid_renewable = false, -- Disallow any kind of spreading
|
||||||
|
-- liquid_range = 2,
|
||||||
|
|
||||||
|
-- buildable_to = true, -- For liquid_alternative_source = "test_water:test",
|
||||||
|
|
||||||
|
-- liquid_alternative_flowing = source_liquid_name, -- As requested in documentation
|
||||||
|
|
||||||
|
-- liquid_move_physics = true,
|
||||||
|
-- walkable = false,
|
||||||
|
|
||||||
|
-- })
|
||||||
|
|
||||||
|
core.override_item(source_liquid_name, {
|
||||||
|
paramtype2 = "flowingliquid",
|
||||||
|
drawtype = "flowingliquid",
|
||||||
|
liquidtype = "",
|
||||||
|
liquid_renewable = false,
|
||||||
|
liquid_range = 2,
|
||||||
|
liquid_alternative_source = "",
|
||||||
|
liquid_alternative_flowing = source_liquid_name,
|
||||||
|
liquid_move_physics = true,
|
||||||
|
special_tiles = source_liquid_def.tiles,
|
||||||
|
groups = source_liquid_def.groups,
|
||||||
|
pointable = true,
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
-- core.register_node(":" .. source_liquid_name, source_liquid_def)
|
||||||
liquid_physics._liquid_ids[source_liquid_name] = id
|
liquid_physics._liquid_ids[source_liquid_name] = id
|
||||||
|
|
||||||
local liquids = {}
|
local liquids = {}
|
||||||
table.insert(liquids, "air")
|
table.insert(liquids, "air")
|
||||||
|
|
||||||
for i = 1, 7 do
|
for i = 1, 7 do
|
||||||
local node_name = "liquid_physics:" .. namespace .. "_" .. source_name .. "_level_" .. i
|
liquid_physics._liquid_ids[source_liquid_name] = id
|
||||||
|
table.insert(liquids, source_liquid_name)
|
||||||
local level_def = {
|
|
||||||
name = node_name,
|
|
||||||
description = source_liquid_def.description .. " Level " .. i,
|
|
||||||
tiles = source_liquid_def.tiles,
|
|
||||||
use_texture_alpha = source_liquid_def.use_texture_alpha,
|
|
||||||
paramtype = source_liquid_def.paramtype,
|
|
||||||
walkable = source_liquid_def.walkable,
|
|
||||||
pointable = source_liquid_def.pointable,
|
|
||||||
diggable = source_liquid_def.diggable,
|
|
||||||
buildable_to = source_liquid_def.buildable_to,
|
|
||||||
is_ground_content = source_liquid_def.is_ground_content,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
drop = source_liquid_def.drop,
|
|
||||||
drowning = source_liquid_def.drowning,
|
|
||||||
liquidtype = "source",
|
|
||||||
liquid_alternative_flowing = node_name,
|
|
||||||
liquid_alternative_source = node_name,
|
|
||||||
liquid_range = 0,
|
|
||||||
liquid_viscosity = source_liquid_def.liquid_viscosity,
|
|
||||||
liquid_renewable = false,
|
|
||||||
waving = source_liquid_def.waving,
|
|
||||||
color = source_liquid_def.color,
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{ -0.5, -0.5, -0.5, 0.5, -0.375 + (0.125 * (i - 1)), 0.5 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
collision_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = { { -0.5, -0.5, -0.5, 0.5, -0.375 + (0.125 * (i - 1)), 0.5 }, },
|
|
||||||
},
|
|
||||||
post_effect_color = source_liquid_def.post_effect_color,
|
|
||||||
groups = source_liquid_def.groups,
|
|
||||||
sounds = source_liquid_def.sounds,
|
|
||||||
}
|
|
||||||
|
|
||||||
core.register_node(":" .. node_name, level_def)
|
|
||||||
liquid_physics._liquid_ids[node_name] = id
|
|
||||||
|
|
||||||
table.insert(liquids, node_name)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- for i = 1, 7 do
|
||||||
|
-- local node_name = "liquid_physics:" .. namespace .. "_" .. source_name .. "_level_" .. i
|
||||||
|
|
||||||
|
-- local level_def = {
|
||||||
|
-- name = node_name,
|
||||||
|
-- description = source_liquid_def.description .. " Level " .. i,
|
||||||
|
-- tiles = source_liquid_def.tiles,
|
||||||
|
-- use_texture_alpha = source_liquid_def.use_texture_alpha,
|
||||||
|
-- paramtype = source_liquid_def.paramtype,
|
||||||
|
-- walkable = source_liquid_def.walkable,
|
||||||
|
-- pointable = source_liquid_def.pointable,
|
||||||
|
-- diggable = source_liquid_def.diggable,
|
||||||
|
-- buildable_to = source_liquid_def.buildable_to,
|
||||||
|
-- is_ground_content = source_liquid_def.is_ground_content,
|
||||||
|
-- drawtype = "nodebox",
|
||||||
|
-- drop = source_liquid_def.drop,
|
||||||
|
-- drowning = source_liquid_def.drowning,
|
||||||
|
-- liquidtype = "source",
|
||||||
|
-- liquid_alternative_flowing = node_name,
|
||||||
|
-- liquid_alternative_source = node_name,
|
||||||
|
-- liquid_range = 0,
|
||||||
|
-- liquid_viscosity = source_liquid_def.liquid_viscosity,
|
||||||
|
-- liquid_renewable = false,
|
||||||
|
-- waving = source_liquid_def.waving,
|
||||||
|
-- color = source_liquid_def.color,
|
||||||
|
-- node_box = {
|
||||||
|
-- type = "fixed",
|
||||||
|
-- fixed = {
|
||||||
|
-- { -0.5, -0.5, -0.5, 0.5, -0.375 + (0.125 * (i - 1)), 0.5 },
|
||||||
|
-- },
|
||||||
|
-- },
|
||||||
|
-- collision_box = {
|
||||||
|
-- type = "fixed",
|
||||||
|
-- fixed = { { -0.5, -0.5, -0.5, 0.5, -0.375 + (0.125 * (i - 1)), 0.5 }, },
|
||||||
|
-- },
|
||||||
|
-- post_effect_color = source_liquid_def.post_effect_color,
|
||||||
|
-- groups = source_liquid_def.groups,
|
||||||
|
-- sounds = source_liquid_def.sounds,
|
||||||
|
-- }
|
||||||
|
|
||||||
|
-- core.register_node(":" .. node_name, level_def)
|
||||||
|
-- liquid_physics._liquid_ids[node_name] = id
|
||||||
|
|
||||||
|
-- table.insert(liquids, node_name)
|
||||||
|
-- end
|
||||||
|
|
||||||
table.insert(liquids, source_liquid_name)
|
table.insert(liquids, source_liquid_name)
|
||||||
|
|
||||||
-- Finally, stop flowing
|
-- Finally, stop flowing
|
||||||
@@ -167,7 +209,9 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
|||||||
core.override_item(flowing_liquid_name, {
|
core.override_item(flowing_liquid_name, {
|
||||||
liquid_range = 0,
|
liquid_range = 0,
|
||||||
liquid_renewable = false,
|
liquid_renewable = false,
|
||||||
groups = flowing_liquid_def.groups
|
liquid_alternative_source = "",
|
||||||
|
liquid_alternative_flowing = "",
|
||||||
|
groups = flowing_liquid_def.groups,
|
||||||
}, nil)
|
}, nil)
|
||||||
liquid_physics._liquid_ids[flowing_liquid_name] = id
|
liquid_physics._liquid_ids[flowing_liquid_name] = id
|
||||||
|
|
||||||
|
|||||||
52
init.lua
52
init.lua
@@ -37,40 +37,28 @@ else
|
|||||||
end
|
end
|
||||||
|
|
||||||
core.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
core.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
||||||
--core.chat_send_all("Placed AT: " .. dump(pos) .. "___")
|
if internal.get_liquid_id(core.get_node(pos).name) ~= nil then
|
||||||
-- if internal.get_liquid_id(core.get_node(pos).name) ~= nil then
|
internal.add_node_to_check(pos)
|
||||||
-- internal.add_node_to_check(pos)
|
end
|
||||||
-- end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- core.register_lbm {
|
core.register_lbm {
|
||||||
-- name = "liquid_physics:update",
|
name = "liquid_physics:update",
|
||||||
-- nodenames = "group:liquid_physics",
|
nodenames = "group:liquid_physics",
|
||||||
-- run_at_every_load = true,
|
run_at_every_load = true,
|
||||||
-- action = function(pos, node, dtime_s)
|
action = function(pos, node, dtime_s)
|
||||||
-- --internal.add_node_to_check(pos)
|
internal.add_node_to_check(pos)
|
||||||
-- core.set_node(pos, { name = "air" })
|
end,
|
||||||
-- end,
|
}
|
||||||
-- }
|
|
||||||
|
|
||||||
-- core.register_lbm {
|
core.register_abm({
|
||||||
-- name = "liquid_physics:update",
|
nodenames = "group:liquid_physics",
|
||||||
-- nodenames = "group:liquid_physics",
|
neighbors = { "air" },
|
||||||
-- run_at_every_load = true,
|
interval = 0.2,
|
||||||
-- action = function(pos, node, dtime_s)
|
chance = 0,
|
||||||
-- --internal.add_node_to_check(pos)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
-- core.set_node(pos, { name = "air" })
|
internal.add_node_to_check(pos)
|
||||||
-- end,
|
end
|
||||||
-- }
|
})
|
||||||
|
|
||||||
-- core.register_abm({
|
|
||||||
-- nodenames = "group:liquid_physics",
|
|
||||||
-- neighbors = { "air" },
|
|
||||||
-- interval = 0.2,
|
|
||||||
-- chance = 0,
|
|
||||||
-- action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
-- --internal.add_node_to_check(pos)
|
|
||||||
-- end
|
|
||||||
-- })
|
|
||||||
|
|
||||||
dofile(modpath .. "/physics.lua")
|
dofile(modpath .. "/physics.lua")
|
||||||
|
|||||||
15
internal.lua
15
internal.lua
@@ -74,7 +74,13 @@ function internal.new_lpn(hash, pos)
|
|||||||
local liquid_id = internal.get_liquid_id(node.name)
|
local liquid_id = internal.get_liquid_id(node.name)
|
||||||
local liquid_level = -1
|
local liquid_level = -1
|
||||||
if liquid_id then
|
if liquid_id then
|
||||||
liquid_level = internal.get_liquid_level(liquid_id, node.name)
|
local node_level = core.get_node_level(pos)
|
||||||
|
if liquid_id == 0 then
|
||||||
|
node_level = 0
|
||||||
|
elseif node_level == 0 and node.name == liquid_physics.get_liquid_node_names(liquid_id)[8] then
|
||||||
|
node_level = 8
|
||||||
|
end
|
||||||
|
liquid_level = node_level --internal.get_liquid_level(liquid_id, node.name)
|
||||||
end
|
end
|
||||||
return {
|
return {
|
||||||
hash = hash,
|
hash = hash,
|
||||||
@@ -83,9 +89,6 @@ function internal.new_lpn(hash, pos)
|
|||||||
liquid_id = liquid_id,
|
liquid_id = liquid_id,
|
||||||
init_liquid_level = liquid_level,
|
init_liquid_level = liquid_level,
|
||||||
liquid_level = liquid_level,
|
liquid_level = liquid_level,
|
||||||
density = 0,
|
|
||||||
gradient = { x = 0, y = 0, z = 0 },
|
|
||||||
neighbors = {},
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -103,14 +106,14 @@ end
|
|||||||
-- @param lpn table Liquid Physics Node
|
-- @param lpn table Liquid Physics Node
|
||||||
function internal.set_node(lpn)
|
function internal.set_node(lpn)
|
||||||
core.set_node(lpn.pos, { name = internal.get_liquid_node_name(lpn.liquid_id, lpn.liquid_level) })
|
core.set_node(lpn.pos, { name = internal.get_liquid_node_name(lpn.liquid_id, lpn.liquid_level) })
|
||||||
|
core.set_node_level(lpn.pos, lpn.liquid_level)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This node will be checked in the next cycle
|
-- This node will be checked in the next cycle
|
||||||
-- @param pos table Position of the node
|
-- @param pos table Position of the node
|
||||||
function internal.add_node_to_check(pos)
|
function internal.add_node_to_check(pos)
|
||||||
local h = core.hash_node_position(pos)
|
local h = core.hash_node_position(pos)
|
||||||
local lpn = internal.new_lpn(h, pos)
|
liquid_physics._nodes_to_check[h] = pos
|
||||||
liquid_physics._nodes_to_check[h] = lpn
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This node will no longer be checked
|
-- This node will no longer be checked
|
||||||
|
|||||||
421
physics.lua
421
physics.lua
@@ -17,30 +17,12 @@ local modpath = core.get_modpath(core.get_current_modname())
|
|||||||
local internal = dofile(modpath .. "/internal.lua")
|
local internal = dofile(modpath .. "/internal.lua")
|
||||||
|
|
||||||
-- A table of offsets for ease of use
|
-- A table of offsets for ease of use
|
||||||
local offsets = {}
|
local offsets = {
|
||||||
-- local offsets = {
|
{ x = 0, z = 1, },
|
||||||
-- { x = 0, z = 0, y = 0, d = 0 },
|
{ x = 0, z = -1, },
|
||||||
|
{ x = 1, z = 0, },
|
||||||
-- { x = 0, z = 1, y = 0, d = 1 },
|
{ x = -1, z = 0, }
|
||||||
-- { x = 0, z = -1, y = 0, d = 1 },
|
}
|
||||||
|
|
||||||
-- { x = 1, z = 0, y = 0, d = 1 },
|
|
||||||
-- { x = -1, z = 0, y = 0, d = 1 },
|
|
||||||
-- }
|
|
||||||
for x = -1, 1 do
|
|
||||||
for y = -1, 1 do
|
|
||||||
for z = -1, 1 do
|
|
||||||
local d = math.abs(x) + math.abs(y) + math.abs(z)
|
|
||||||
table.insert(offsets, {
|
|
||||||
x = x, -- X Offset
|
|
||||||
y = y, -- Y Offset
|
|
||||||
z = z, -- Z Offset
|
|
||||||
d = d -- Distance to 0 / 0 / 0
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Store number of offsets for less calculations
|
-- Store number of offsets for less calculations
|
||||||
local number_of_offsets = table.getn(offsets)
|
local number_of_offsets = table.getn(offsets)
|
||||||
|
|
||||||
@@ -51,8 +33,8 @@ local number_of_offsets = table.getn(offsets)
|
|||||||
local function add_offset_to_pos(pos, offset)
|
local function add_offset_to_pos(pos, offset)
|
||||||
return {
|
return {
|
||||||
x = pos.x + offset.x,
|
x = pos.x + offset.x,
|
||||||
y = pos.y + offset.y,
|
|
||||||
z = pos.z + offset.z,
|
z = pos.z + offset.z,
|
||||||
|
y = pos.y
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -70,16 +52,6 @@ local function get_lpn_buffered(b, pos)
|
|||||||
return b[h]
|
return b[h]
|
||||||
end
|
end
|
||||||
|
|
||||||
local function round_away_from_zero(value)
|
|
||||||
if value == 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
if value > 0 then
|
|
||||||
return math.ceil(value)
|
|
||||||
end
|
|
||||||
return math.floor(value) -- Let's hope math floor is optimized for zero
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Checks if liquid_id of curr and lpn are the same.
|
-- Checks if liquid_id of curr and lpn are the same.
|
||||||
-- Checks if the liquid_level is above -1
|
-- Checks if the liquid_level is above -1
|
||||||
-- @param curr table The current LPN
|
-- @param curr table The current LPN
|
||||||
@@ -89,203 +61,25 @@ local function is_lpn_relevant(curr, lpn)
|
|||||||
return lpn.liquid_level >= 0 and (lpn.liquid_level == 0 or curr.liquid_id == lpn.liquid_id)
|
return lpn.liquid_level >= 0 and (lpn.liquid_level == 0 or curr.liquid_id == lpn.liquid_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- local function get_gradient(base, compare, opp)
|
|
||||||
-- local compare_copy = compare
|
|
||||||
-- if compare_copy < 0 then compare_copy = 0 end
|
|
||||||
-- return math.ceil(((opp + base) - compare_copy * 2) / 8)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- Gets all adjacent liquid nodes with the same liquid_id as curr
|
-- Gets all adjacent liquid nodes with the same liquid_id as curr
|
||||||
-- Gets all adjacent air nodes
|
-- Gets all adjacent air nodes
|
||||||
-- @param b table Buffered LPN
|
-- @param b table Buffered LPN
|
||||||
-- @param curr table The current LPN
|
-- @param curr table The current LPN
|
||||||
-- @return table Table of neighboring LPN
|
-- @return table Table of neighboring LPN
|
||||||
-- @return number Number of neighbors
|
-- @return number Number of neighbors
|
||||||
local function get_all_neighbors_pressure(b, curr)
|
local function get_valid_neighbors(b, curr)
|
||||||
local neighbors = {}
|
local neighbors = {}
|
||||||
local no_of_h_neighbors = 0
|
local number_of_neighbors = 0
|
||||||
local no_of_v_neighbors = 0
|
|
||||||
for i = 1, number_of_offsets do
|
for i = 1, number_of_offsets do
|
||||||
local current_offset = offsets[i]
|
local pos = add_offset_to_pos(curr.pos, offsets[i])
|
||||||
local pos = add_offset_to_pos(curr.pos, current_offset)
|
|
||||||
local lpn = get_lpn_buffered(b, pos)
|
local lpn = get_lpn_buffered(b, pos)
|
||||||
|
|
||||||
--if is_lpn_relevant(curr, lpn) then
|
if is_lpn_relevant(curr, lpn) then
|
||||||
|
number_of_neighbors = number_of_neighbors + 1
|
||||||
local o_off = {}
|
table.insert(neighbors, math.random(number_of_neighbors, 1), lpn)
|
||||||
if i % 2 == 0 then
|
|
||||||
o_off = offsets[i - 1]
|
|
||||||
else
|
|
||||||
o_off = offsets[i + 1]
|
|
||||||
end
|
|
||||||
|
|
||||||
local o_pos = add_offset_to_pos(curr.pos, o_off)
|
|
||||||
local o_lpn = get_lpn_buffered(b, o_pos)
|
|
||||||
|
|
||||||
local g = current_offset.g + get_gradient(curr.liquid_level, lpn.liquid_level, o_lpn.liquid_level)
|
|
||||||
|
|
||||||
if g ~= 0 then
|
|
||||||
if i < 5 then
|
|
||||||
no_of_h_neighbors = no_of_h_neighbors + 1
|
|
||||||
else
|
|
||||||
no_of_v_neighbors = no_of_v_neighbors + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.insert(neighbors, { lpn = lpn, g = g })
|
|
||||||
--end
|
|
||||||
end
|
|
||||||
return neighbors, no_of_h_neighbors, no_of_v_neighbors
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function get_pressure_gradient(b, lpn)
|
|
||||||
local number_of_directions = 0
|
|
||||||
|
|
||||||
lpn.neighbors = get_all_neighbors_pressure(b, lpn)
|
|
||||||
|
|
||||||
lpn.pressure_gradient = internal.get_inital_pressure_gradient()
|
|
||||||
|
|
||||||
local i = 1
|
|
||||||
for _, g in pairs(lpn.pressure_gradient) do
|
|
||||||
g = g + get_gradient(lpn.liquid_level, lpn.neighbors[i].liquid_level)
|
|
||||||
i = i + 1
|
|
||||||
if g ~= 0 then
|
|
||||||
number_of_directions = number_of_directions + 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return neighbors, number_of_neighbors
|
||||||
return number_of_directions
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_density_influence(r, d)
|
|
||||||
local vol = math.pi * (r ^ 8) / 4
|
|
||||||
local v = math.max(0, r - d)
|
|
||||||
return v + v * v / vol
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_density_influence_derivative(r, d)
|
|
||||||
if (d >= r) then return 0 end
|
|
||||||
local f = r * r - d * d
|
|
||||||
local scale = -24 / (math.pi * (r ^ 8))
|
|
||||||
return scale * d * f * f
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_density(b, lpn)
|
|
||||||
local radius = 3 -- 3 is max
|
|
||||||
for i = 1, number_of_offsets do
|
|
||||||
local offset = offsets[i]
|
|
||||||
local o_pos = add_offset_to_pos(lpn.pos, offset)
|
|
||||||
local o_lpn = get_lpn_buffered(b, o_pos)
|
|
||||||
|
|
||||||
local liquid_level = o_lpn.liquid_level
|
|
||||||
if liquid_level < 0 then
|
|
||||||
liquid_level = lpn.liquid_level
|
|
||||||
elseif liquid_level == 0 then
|
|
||||||
liquid_level = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if offset.d == 0 then
|
|
||||||
-- liquid_level = 0
|
|
||||||
-- end
|
|
||||||
|
|
||||||
local influence = liquid_level * get_density_influence(radius, offset.d)
|
|
||||||
|
|
||||||
table.insert(lpn.neighbors, { lpn = o_lpn, prs = 0 })
|
|
||||||
|
|
||||||
lpn.density = lpn.density + influence
|
|
||||||
end
|
|
||||||
lpn.density = math.floor(lpn.density)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function get_pressure_from_density(density)
|
|
||||||
local multiplier = 1
|
|
||||||
local target_pressure = 11
|
|
||||||
--core.chat_send_all(density)
|
|
||||||
return (density - target_pressure) * multiplier
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_gradient(b, lpn)
|
|
||||||
-- local gradient = {
|
|
||||||
-- x = 0,
|
|
||||||
-- y = 0,
|
|
||||||
-- z = 0,
|
|
||||||
-- }
|
|
||||||
local radius = 3 -- 3 is max
|
|
||||||
|
|
||||||
for i = 1, number_of_offsets do
|
|
||||||
local offset = offsets[i]
|
|
||||||
|
|
||||||
if offset.d == 0 then
|
|
||||||
goto continue
|
|
||||||
end
|
|
||||||
|
|
||||||
local neighbor = lpn.neighbors[i].lpn
|
|
||||||
|
|
||||||
local density = neighbor.density
|
|
||||||
|
|
||||||
-- if density < 0 then
|
|
||||||
-- density = neighbor.density
|
|
||||||
-- else
|
|
||||||
if density == 0 then
|
|
||||||
density = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local slope = get_density_influence_derivative(radius, offset.d)
|
|
||||||
local pressure = get_pressure_from_density(density)
|
|
||||||
|
|
||||||
--if offset.y == 0 then
|
|
||||||
lpn.neighbors[i].prs = math.ceil(math.abs(
|
|
||||||
(pressure * slope * lpn.liquid_level / density)))
|
|
||||||
|
|
||||||
lpn.neighbors[i].is_down = false
|
|
||||||
|
|
||||||
if offset.y == 1 then
|
|
||||||
lpn.neighbors[i].prs = lpn.neighbors[i].prs - 6
|
|
||||||
end
|
|
||||||
|
|
||||||
if offset.y == -1 then
|
|
||||||
lpn.neighbors[i].prs = 1
|
|
||||||
lpn.neighbors[i].is_down = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- lpn.gradient = {
|
|
||||||
-- x = lpn.gradient.x + (pressure * offset.x * slope * neighbor.liquid_level / density),
|
|
||||||
-- y = lpn.gradient.y + (pressure * offset.y * slope * neighbor.liquid_level / density),
|
|
||||||
-- z = lpn.gradient.z + (pressure * offset.z * slope * neighbor.liquid_level / density),
|
|
||||||
-- }
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
|
|
||||||
--core.chat_send_all("Pressure: " .. dump(lpn.gradient))
|
|
||||||
|
|
||||||
-- lpn.gradient = {
|
|
||||||
-- x = round_away_from_zero(lpn.gradient.x),
|
|
||||||
-- y = round_away_from_zero(lpn.gradient.y),
|
|
||||||
-- z = round_away_from_zero(lpn.gradient.z),
|
|
||||||
-- }
|
|
||||||
-- if lpn.gradient.x > 0 then
|
|
||||||
-- lpn.gradient.x = 1
|
|
||||||
-- elseif lpn.gradient.x < 0 then
|
|
||||||
-- lpn.gradient.x = -1
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- if lpn.gradient.y > 0 then
|
|
||||||
-- lpn.gradient.y = 1
|
|
||||||
-- elseif lpn.gradient.y < 0 then
|
|
||||||
-- lpn.gradient.y = -1
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- if lpn.gradient.z > 0 then
|
|
||||||
-- lpn.gradient.z = 1
|
|
||||||
-- elseif lpn.gradient.z < 0 then
|
|
||||||
-- lpn.gradient.z = -1
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function get_pressure_force(lpn)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Gets neighbors of curr and calculates the pressure
|
-- Gets neighbors of curr and calculates the pressure
|
||||||
@@ -333,9 +127,6 @@ local function try_move(from, to, amount)
|
|||||||
if to.liquid_level >= 8 then
|
if to.liquid_level >= 8 then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
if amount <= 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
local max_allowed = amount + 8 - (to.liquid_level + amount)
|
local max_allowed = amount + 8 - (to.liquid_level + amount)
|
||||||
local max_allowed_clamped = math.min(max_allowed, amount, from.liquid_level)
|
local max_allowed_clamped = math.min(max_allowed, amount, from.liquid_level)
|
||||||
|
|
||||||
@@ -421,179 +212,21 @@ local function move(b, curr_pos)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function try_spread(buffer, from, to, is_down)
|
|
||||||
if is_lpn_relevant(from, to) and ((from.liquid_level > 1 and from.liquid_level >= to.liquid_level + 1) or is_down) then
|
|
||||||
return try_move(from, to, 1)
|
|
||||||
end
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local function shuffle(array)
|
|
||||||
math.randomseed(os.time()) -- Seed the random number generator
|
|
||||||
for i = #array, 2, -1 do
|
|
||||||
local j = math.random(i) -- Pick a random index from 1 to i
|
|
||||||
array[i], array[j] = array[j], array[i] -- Swap elements
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local last_finish = 0
|
|
||||||
local active_blocks = {}
|
|
||||||
|
|
||||||
core.register_on_liquid_transformed(function(pos_list, node_list)
|
|
||||||
for hash, block_start in pairs(active_blocks) do
|
|
||||||
if core.compare_block_status(block_start, "active") then
|
|
||||||
else
|
|
||||||
active_blocks[hash] = nil
|
|
||||||
goto continue
|
|
||||||
end
|
|
||||||
|
|
||||||
--core.chat_send_all(dump(block_start) .. "----" .. modified_blocks_count)
|
|
||||||
local buffer = {}
|
|
||||||
local block_end = {
|
|
||||||
x = block_start.x + 15,
|
|
||||||
y = block_start.y + 15,
|
|
||||||
z = block_start.z + 15,
|
|
||||||
}
|
|
||||||
local node_pos_list = core.find_nodes_in_area(block_start, block_end, { "group:liquid_physics" })
|
|
||||||
|
|
||||||
local lpn_list = {}
|
|
||||||
local number_of_lpn = 0
|
|
||||||
for _, pos in pairs(node_pos_list) do
|
|
||||||
local lpn = get_lpn_buffered(buffer, pos)
|
|
||||||
get_density(buffer, lpn)
|
|
||||||
|
|
||||||
table.insert(lpn_list, lpn)
|
|
||||||
number_of_lpn = number_of_lpn + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, number_of_lpn do
|
|
||||||
local g_lpn = lpn_list[i]
|
|
||||||
get_gradient(buffer, g_lpn)
|
|
||||||
|
|
||||||
--g_lpn.gradient.y = 0
|
|
||||||
|
|
||||||
--core.chat_send_all("Grad: " .. dump(g_lpn.gradient))
|
|
||||||
|
|
||||||
-- local spread_to_pos = add_offset_to_pos(g_lpn.pos, g_lpn.gradient)
|
|
||||||
-- local spread_to = get_lpn_buffered(buffer, spread_to_pos)
|
|
||||||
|
|
||||||
-- try_spread(buffer, g_lpn, spread_to)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- local gs = 0
|
|
||||||
-- for g = 1, number_of_offsets do
|
|
||||||
-- if g_lpn.neighbors[g].prs > 0 then
|
|
||||||
-- gs = gs + 1
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
local number_of_targets = 0
|
|
||||||
for g = 1, number_of_offsets do
|
|
||||||
if g_lpn.neighbors[g].prs > 0 and not g_lpn.neighbors[g].is_down then
|
|
||||||
number_of_targets = number_of_targets + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if number_of_targets >= g_lpn.liquid_level then
|
|
||||||
shuffle(g_lpn.neighbors)
|
|
||||||
end
|
|
||||||
|
|
||||||
for g = 1, number_of_offsets do
|
|
||||||
if g_lpn.neighbors[g].prs > 0 then
|
|
||||||
try_spread(buffer, g_lpn, g_lpn.neighbors[g].lpn, g_lpn.neighbors[g].is_down)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- if g_lpn.gradient.x ~= 0 then
|
|
||||||
-- local spread_to_pos = add_offset_to_pos(g_lpn.pos, { x = g_lpn.gradient.x, y = 0, z = 0 })
|
|
||||||
-- local spread_to = get_lpn_buffered(buffer, spread_to_pos)
|
|
||||||
|
|
||||||
-- try_spread(buffer, g_lpn, spread_to)
|
|
||||||
-- -- if try_spread(buffer, g_lpn, spread_to, gs) == 0 then
|
|
||||||
-- -- spread_to_pos = add_offset_to_pos(g_lpn.pos, { x = g_lpn.gradient.x * -1, y = 0, z = 0 })
|
|
||||||
-- -- spread_to = get_lpn_buffered(buffer, spread_to_pos)
|
|
||||||
-- -- try_spread(buffer, g_lpn, spread_to, gs)
|
|
||||||
-- -- end
|
|
||||||
-- end
|
|
||||||
-- if g_lpn.gradient.z ~= 0 then
|
|
||||||
-- local spread_to_pos = add_offset_to_pos(g_lpn.pos, { x = 0, y = 0, z = g_lpn.gradient.z })
|
|
||||||
-- local spread_to = get_lpn_buffered(buffer, spread_to_pos)
|
|
||||||
|
|
||||||
-- try_spread(buffer, g_lpn, spread_to)
|
|
||||||
-- -- if try_spread(buffer, g_lpn, spread_to, gs) == 0 then
|
|
||||||
-- -- spread_to_pos = add_offset_to_pos(g_lpn.pos, { x = 0, y = 0, z = g_lpn.gradient.z * -1 })
|
|
||||||
-- -- spread_to = get_lpn_buffered(buffer, spread_to_pos)
|
|
||||||
-- -- try_spread(buffer, g_lpn, spread_to, gs)
|
|
||||||
-- -- end
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
if lpn_list[1] ~= nil then
|
|
||||||
end
|
|
||||||
|
|
||||||
-- for _, pos in pairs(node_pos_list) do
|
|
||||||
-- local lpn = get_lpn_buffered(buffer, pos)
|
|
||||||
|
|
||||||
-- local neighbors, h, v = get_all_neighbors_pressure(buffer, lpn)
|
|
||||||
|
|
||||||
-- local n = 0
|
|
||||||
-- for i = 1, number_of_offsets do
|
|
||||||
-- if neighbors[i].g == 0 then
|
|
||||||
-- goto continue
|
|
||||||
-- end
|
|
||||||
-- if i < 5 then
|
|
||||||
-- n = h
|
|
||||||
-- else
|
|
||||||
-- n = v - 1
|
|
||||||
-- end
|
|
||||||
-- try_spread(buffer, lpn, neighbors[i].lpn, n, neighbors[i].g)
|
|
||||||
-- ::continue::
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- ::continue::
|
|
||||||
--
|
|
||||||
for _, lpn in pairs(buffer) do
|
|
||||||
if lpn.init_liquid_level ~= lpn.liquid_level then
|
|
||||||
if lpn.liquid_id then
|
|
||||||
internal.set_node(lpn)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
core.register_on_mapblocks_changed(function(modified_blocks, modified_blocks_count)
|
core.register_on_mapblocks_changed(function(modified_blocks, modified_blocks_count)
|
||||||
for hash, _ in pairs(modified_blocks) do
|
-- Buffered LPN
|
||||||
local block_start = core.get_position_from_hash(hash)
|
local b = {}
|
||||||
|
for hpos, pos in pairs(liquid_physics._nodes_to_check) do
|
||||||
block_start = {
|
if core.compare_block_status(pos, "active") then
|
||||||
x = block_start.x * 16,
|
move(b, pos)
|
||||||
y = block_start.y * 16,
|
|
||||||
z = block_start.z * 16,
|
|
||||||
}
|
|
||||||
|
|
||||||
if core.compare_block_status(block_start, "active") then
|
|
||||||
active_blocks[hash] = block_start
|
|
||||||
else
|
else
|
||||||
active_blocks[hash] = nil
|
internal.remove_node_to_check(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Update only changed nodes from buffer
|
||||||
|
for _, lpn in pairs(b) do
|
||||||
|
--core.chat_send_all(dump(lpn))
|
||||||
|
if lpn.init_liquid_level ~= lpn.liquid_level then
|
||||||
|
internal.set_node(lpn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- -- Buffered LPN
|
|
||||||
-- local b = {}
|
|
||||||
-- for hpos, pos in pairs(liquid_physics._nodes_to_check) do
|
|
||||||
-- if core.compare_block_status(pos, "active") then
|
|
||||||
-- move(b, pos)
|
|
||||||
-- else
|
|
||||||
-- internal.remove_node_to_check(pos)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- -- Update only changed nodes from buffer
|
|
||||||
-- for _, lpn in pairs(b) do
|
|
||||||
-- if lpn.init_liquid_level ~= lpn.liquid_level then
|
|
||||||
-- internal.set_node(lpn)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user