Update API & Add Documentation
This commit is contained in:
parent
f0f9c5f2d4
commit
3ecba778ce
83
api.lua
83
api.lua
@ -13,56 +13,53 @@
|
|||||||
-- You should have received a copy of the GNU Affero General Public License
|
-- You should have received a copy of the GNU Affero General Public License
|
||||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
--Stores liquid_id and the corresponding liquid node names
|
local modpath = core.get_modpath(core.get_current_modname())
|
||||||
liquid_physics.registered_liquids = {}
|
local internal = dofile(modpath .. "/internal.lua")
|
||||||
|
|
||||||
--Stores all liquid node names and their corresponding liquid_id
|
-- Returns liquid_id of the node or
|
||||||
local liquid_ids = {}
|
-- nil when the node is not a liquid
|
||||||
|
-- @param node_name string Name of the node, e.g. "default:water_source"
|
||||||
-- Returns liquid_id when node is a liquid, 0 when node is air
|
-- @return number ID of the liquid
|
||||||
-- and nil when node is anything else
|
|
||||||
-- Note: 0 is not a valid ID
|
|
||||||
function liquid_physics.get_liquid_id(node_name)
|
function liquid_physics.get_liquid_id(node_name)
|
||||||
if node_name == "air" then
|
return internal.get_liquid_id(node_name)
|
||||||
return 0
|
|
||||||
end
|
|
||||||
return liquid_ids[node_name]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--Returns name of liquid node. Note: if liquid_level == 0 then "air" will be returned
|
-- Returns the liquid of the position specified or
|
||||||
function liquid_physics.get_liquid_node_name(liquid_id, liquid_level)
|
-- nil when the node is not a liquid
|
||||||
if liquid_level == 0 then
|
-- @param pos table Position of the Node
|
||||||
return "air"
|
-- @return table Table with liquid_id and liquid_level
|
||||||
|
function liquid_physics.get_liquid_at(pos)
|
||||||
|
local lpn = internal.new_lpn(core.hash_node_position(pos), pos)
|
||||||
|
if not lpn.liquid_id then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return { liquid_id = lpn.liquid_id, liquid_level = lpn.liquid_level }
|
||||||
end
|
end
|
||||||
|
|
||||||
return liquid_physics.registered_liquids[liquid_id][liquid_level + 1]
|
-- Sets the liquid at the position specified
|
||||||
|
-- Returns true if the operation was successful
|
||||||
|
-- @param pos table Position of the Node
|
||||||
|
-- @param liquid_id number ID of the liquid
|
||||||
|
-- @param liquid_level number [0..8] Level of the liquid
|
||||||
|
-- @return bool Success
|
||||||
|
function liquid_physics.set_liquid_at(pos, liquid_id, liquid_level)
|
||||||
|
if liquid_level > 8 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local lpn = internal.new_lpn(core.hash_node_position(pos), pos)
|
||||||
|
internal.set_lpn(liquid_id, lpn, liquid_level)
|
||||||
|
internal.add_node_to_check(pos)
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--Returns the liquid level. If the node is air, 0 will be returned.
|
-- Executing this function will override the nodes specified.
|
||||||
-- -1 will be returned for any other node
|
|
||||||
function liquid_physics.get_liquid_level(liquid_id, node_name)
|
|
||||||
if node_name == "air" then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
if liquid_physics.registered_liquids[liquid_id] == nil then
|
|
||||||
error(liquid_id)
|
|
||||||
end
|
|
||||||
for i = 1, 9 do
|
|
||||||
if node_name == liquid_physics.registered_liquids[liquid_id][i] then
|
|
||||||
return i - 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return -1
|
|
||||||
end
|
|
||||||
|
|
||||||
--@param namespace string Name of mod eg. default
|
|
||||||
--@param name string Name of former liquid source
|
|
||||||
-- Executing this function will override the liquid source specified.
|
|
||||||
-- New liquid sources will be "liquid_physics:namespace_name_level_1" through 7
|
-- New liquid sources will be "liquid_physics:namespace_name_level_1" through 7
|
||||||
|
-- @param namespace string Name of mod e.g. "default"
|
||||||
|
-- @param source_name string Name of the liquid source, e.g. "water_source"
|
||||||
|
-- @param flowing_name string Name of the flowing liquid, e.g. "water_flowing"
|
||||||
function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
||||||
--Get next id
|
--Get next id
|
||||||
local id = table.getn(liquid_physics.registered_liquids) + 1
|
local id = table.getn(liquid_physics._registered_liquids) + 1
|
||||||
|
|
||||||
--Get source definition
|
--Get source definition
|
||||||
local source_liquid_name = namespace .. ":" .. source_name
|
local source_liquid_name = namespace .. ":" .. source_name
|
||||||
@ -89,7 +86,7 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
|||||||
source_liquid_def.liquid_alternative_source = source_liquid_name
|
source_liquid_def.liquid_alternative_source = source_liquid_name
|
||||||
|
|
||||||
core.register_node(":" .. source_liquid_name, source_liquid_def)
|
core.register_node(":" .. source_liquid_name, source_liquid_def)
|
||||||
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")
|
||||||
@ -134,7 +131,7 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
core.register_node(node_name, level_def)
|
core.register_node(node_name, level_def)
|
||||||
liquid_ids[node_name] = id
|
liquid_physics._liquid_ids[node_name] = id
|
||||||
|
|
||||||
table.insert(liquids, node_name)
|
table.insert(liquids, node_name)
|
||||||
end
|
end
|
||||||
@ -149,7 +146,7 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
|||||||
flowing_liquid_def.liquid_alternative_source = source_liquid_name
|
flowing_liquid_def.liquid_alternative_source = source_liquid_name
|
||||||
|
|
||||||
core.register_node(":" .. flowing_liquid_name, flowing_liquid_def)
|
core.register_node(":" .. flowing_liquid_name, flowing_liquid_def)
|
||||||
liquid_ids[flowing_liquid_name] = id
|
liquid_physics._liquid_ids[flowing_liquid_name] = id
|
||||||
|
|
||||||
liquid_physics.registered_liquids[id] = liquids
|
liquid_physics._registered_liquids[id] = liquids
|
||||||
end
|
end
|
||||||
|
41
init.lua
41
init.lua
@ -17,6 +17,14 @@ local modpath = core.get_modpath(core.get_current_modname())
|
|||||||
|
|
||||||
liquid_physics = {}
|
liquid_physics = {}
|
||||||
|
|
||||||
|
--INTERNAL USE ONLY - Stores all nodes which need to checked
|
||||||
|
liquid_physics._nodes_to_check = {}
|
||||||
|
--INTERNAL USE ONLY - Stores liquid_id and the corresponding liquid node names
|
||||||
|
liquid_physics._registered_liquids = {}
|
||||||
|
--INTERNAL USE ONLY - Stores all liquid node names and their corresponding liquid_id
|
||||||
|
liquid_physics._liquid_ids = {}
|
||||||
|
|
||||||
|
local internal = dofile(modpath .. "/internal.lua")
|
||||||
dofile(modpath .. "/api.lua")
|
dofile(modpath .. "/api.lua")
|
||||||
|
|
||||||
if core.get_modpath("default") then
|
if core.get_modpath("default") then
|
||||||
@ -29,4 +37,37 @@ if core.get_modpath("mcl_core") then
|
|||||||
liquid_physics.register_liquid("mcl_core", "lava_source", "lava_flowing")
|
liquid_physics.register_liquid("mcl_core", "lava_source", "lava_flowing")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remove "air" from registered_liquids for lbm and abm
|
||||||
|
local source_names = {}
|
||||||
|
for key, value in pairs(liquid_physics._registered_liquids) do
|
||||||
|
for i = 2, table.getn(value) do
|
||||||
|
table.insert(source_names, value[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
||||||
|
if internal.get_liquid_id(core.get_node(pos).name) ~= nil then
|
||||||
|
internal.add_node_to_check(pos)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
core.register_lbm {
|
||||||
|
name = "liquid_physics:update",
|
||||||
|
nodenames = source_names,
|
||||||
|
run_at_every_load = true,
|
||||||
|
action = function(pos, node, dtime_s)
|
||||||
|
internal.add_node_to_check(pos)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
core.register_abm({
|
||||||
|
nodenames = source_names,
|
||||||
|
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")
|
||||||
|
113
internal.lua
Normal file
113
internal.lua
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
-- Copyright (C) 2025 snoutie
|
||||||
|
-- Authors: snoutie (copyright@achtarmig.org)
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU Affero General Public License as published
|
||||||
|
-- by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
-- You should have received a copy of the GNU Affero General Public License
|
||||||
|
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
local internal = {}
|
||||||
|
|
||||||
|
-- Returns liquid_id when node is a liquid
|
||||||
|
-- 0 when node is air and
|
||||||
|
-- nil when node is anything else
|
||||||
|
-- Note: 0 is not a valid ID
|
||||||
|
-- @param node_name string The name of the node
|
||||||
|
-- @return number The ID of the liquid
|
||||||
|
function internal.get_liquid_id(node_name)
|
||||||
|
if node_name == "air" then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return liquid_physics._liquid_ids[node_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns name of liquid node or
|
||||||
|
-- "air" for a liquid level of 0
|
||||||
|
-- @param liquid_id number The ID of the liquid
|
||||||
|
-- @param liquid_level number The level of the liquid
|
||||||
|
-- @return string Name of the liquid node
|
||||||
|
function internal.get_liquid_node_name(liquid_id, liquid_level)
|
||||||
|
if liquid_level == 0 then
|
||||||
|
return "air"
|
||||||
|
end
|
||||||
|
|
||||||
|
return liquid_physics._registered_liquids[liquid_id][liquid_level + 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the liquid level of the current node, where:
|
||||||
|
-- 0 will be returned for air and
|
||||||
|
-- -1 will be returned for non-liquids.
|
||||||
|
-- @param liquid_id number The ID of the liquid
|
||||||
|
-- @param node_name string The name of the node
|
||||||
|
-- @returns number Level of liquid
|
||||||
|
function internal.get_liquid_level(liquid_id, node_name)
|
||||||
|
if node_name == "air" then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
if liquid_physics._registered_liquids[liquid_id] == nil then
|
||||||
|
error("Invalid liquid_id: " .. liquid_id)
|
||||||
|
end
|
||||||
|
for i = 1, 9 do
|
||||||
|
if node_name == liquid_physics._registered_liquids[liquid_id][i] then
|
||||||
|
return i - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns new Liquid Physics Node (LPN)
|
||||||
|
-- A LPN contains all necessary information for processing
|
||||||
|
-- A liquid_level of -1 or liquid_id of nil means, this node is not a liquid
|
||||||
|
-- @param hash string Hashed position of the node
|
||||||
|
-- @param pos table Position of the node
|
||||||
|
-- @return table LPN
|
||||||
|
function internal.new_lpn(hash, pos)
|
||||||
|
local node = core.get_node(pos)
|
||||||
|
local liquid_id = internal.get_liquid_id(node.name)
|
||||||
|
local liquid_level = -1
|
||||||
|
if liquid_id then
|
||||||
|
liquid_level = internal.get_liquid_level(liquid_id, node.name)
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
hash = hash,
|
||||||
|
pos = pos,
|
||||||
|
node_name = node.name,
|
||||||
|
liquid_id = liquid_id,
|
||||||
|
init_liquid_level = liquid_level,
|
||||||
|
liquid_level = liquid_level,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sets liquid_level and liquid_id of LPN
|
||||||
|
-- Change liquid_id for transmution
|
||||||
|
-- @param liquid_id number The new ID of the liquid
|
||||||
|
-- @param lpn table Liquid Physics Node
|
||||||
|
-- @param liquid_level number The new level of the liquid
|
||||||
|
function internal.set_lpn(liquid_id, lpn, liquid_level)
|
||||||
|
lpn.liquid_level = liquid_level
|
||||||
|
lpn.liquid_id = liquid_id
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This node will be checked in the next cycle
|
||||||
|
-- @param pos table Position of the node
|
||||||
|
function internal.add_node_to_check(pos)
|
||||||
|
local h = core.hash_node_position(pos)
|
||||||
|
liquid_physics._nodes_to_check[h] = pos
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This node will no longer be checked
|
||||||
|
-- @param pos table Position of the node
|
||||||
|
function internal.remove_node_to_check(pos)
|
||||||
|
local h = core.hash_node_position(pos)
|
||||||
|
liquid_physics._nodes_to_check[h] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return internal
|
162
physics.lua
162
physics.lua
@ -13,32 +13,23 @@
|
|||||||
-- You should have received a copy of the GNU Affero General Public License
|
-- You should have received a copy of the GNU Affero General Public License
|
||||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
local modpath = core.get_modpath(core.get_current_modname())
|
||||||
|
local internal = dofile(modpath .. "/internal.lua")
|
||||||
|
|
||||||
|
-- A table of offsets for ease of use
|
||||||
local offsets = {
|
local offsets = {
|
||||||
{ x = 0, z = 1, },
|
{ x = 0, z = 1, },
|
||||||
{ x = 0, z = -1, },
|
{ x = 0, z = -1, },
|
||||||
{ x = 1, z = 0, },
|
{ x = 1, z = 0, },
|
||||||
{ x = -1, z = 0, }
|
{ x = -1, z = 0, }
|
||||||
}
|
}
|
||||||
|
-- Store number of offsets for less calculations
|
||||||
local number_of_offsets = table.getn(offsets)
|
local number_of_offsets = table.getn(offsets)
|
||||||
|
|
||||||
--Nodes which will be checked
|
|
||||||
local nodes_to_check = {}
|
|
||||||
|
|
||||||
--Adds node to check
|
|
||||||
local function add_node_to_check(pos)
|
|
||||||
local h = core.hash_node_position(pos)
|
|
||||||
nodes_to_check[h] = pos
|
|
||||||
end
|
|
||||||
|
|
||||||
--This node will no longer be checked
|
|
||||||
--
|
|
||||||
--"Freezes" node
|
|
||||||
local function remove_node_to_check(pos)
|
|
||||||
local h = core.hash_node_position(pos)
|
|
||||||
nodes_to_check[h] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Adds offset to pos
|
-- Adds offset to pos
|
||||||
|
-- @param pos table Position
|
||||||
|
-- @param offset table Offset
|
||||||
|
-- @return table Position with added offset
|
||||||
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,
|
||||||
@ -47,49 +38,35 @@ local function add_offset_to_pos(pos, offset)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
--Returns new Liquid Physics Node (lpn)
|
-- Get a LPN from either the buffer or create a new one
|
||||||
--A LPN contains all necessary information for processing
|
-- and add it to the buffer
|
||||||
--A liquid_level of -1 means, this node is not a liquid
|
-- @param b table Buffered LPN
|
||||||
local function new_lpn(h, pos)
|
-- @param pos table Positon of the node
|
||||||
local node = core.get_node(pos)
|
-- @return table LPN
|
||||||
local liquid_id = liquid_physics.get_liquid_id(node.name)
|
|
||||||
local liquid_level = -1
|
|
||||||
if liquid_id then
|
|
||||||
liquid_level = liquid_physics.get_liquid_level(liquid_id, node.name)
|
|
||||||
end
|
|
||||||
return {
|
|
||||||
hash = h,
|
|
||||||
pos = pos,
|
|
||||||
node_name = node.name,
|
|
||||||
liquid_id = liquid_id,
|
|
||||||
init_liquid_level = liquid_level,
|
|
||||||
liquid_level = liquid_level,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--Sets liquid_level and liquid_id of LPN
|
|
||||||
--Allows for transmution
|
|
||||||
local function set_lpn(liquid_id, lpn, liquid_level)
|
|
||||||
lpn.liquid_level = liquid_level
|
|
||||||
lpn.liquid_id = liquid_id
|
|
||||||
end
|
|
||||||
|
|
||||||
--Reduce calls to Engine and reduce calculations of liquid_level
|
|
||||||
local function get_lpn_buffered(b, pos)
|
local function get_lpn_buffered(b, pos)
|
||||||
local h = core.hash_node_position(pos)
|
local h = core.hash_node_position(pos)
|
||||||
if b[h] ~= nil then
|
if b[h] ~= nil then
|
||||||
return b[h]
|
return b[h]
|
||||||
end
|
end
|
||||||
b[h] = new_lpn(h, pos)
|
b[h] = internal.new_lpn(h, pos)
|
||||||
return b[h]
|
return b[h]
|
||||||
end
|
end
|
||||||
|
|
||||||
--Checks if liquid_id of curr and lpn are the same. Also if the liquid_level is above -1
|
-- Checks if liquid_id of curr and lpn are the same.
|
||||||
|
-- Checks if the liquid_level is above -1
|
||||||
|
-- @param curr table The current LPN
|
||||||
|
-- @param lpn table The LPN to compare against
|
||||||
|
-- @return bool Is this LPN relevant
|
||||||
local function is_lpn_relevant(curr, lpn)
|
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
|
||||||
|
|
||||||
--Gets all adjacent liquid nodes with the same liquid id, or air nodes
|
-- Gets all adjacent liquid nodes with the same liquid_id as curr
|
||||||
|
-- Gets all adjacent air nodes
|
||||||
|
-- @param b table Buffered LPN
|
||||||
|
-- @param curr table The current LPN
|
||||||
|
-- @return table Table of neighboring LPN
|
||||||
|
-- @return number Number of neighbors
|
||||||
local function get_valid_neighbors(b, curr)
|
local function get_valid_neighbors(b, curr)
|
||||||
local neighbors = {}
|
local neighbors = {}
|
||||||
local number_of_neighbors = 0
|
local number_of_neighbors = 0
|
||||||
@ -107,6 +84,9 @@ end
|
|||||||
|
|
||||||
-- Gets neighbors of curr and calculates the pressure
|
-- Gets neighbors of curr and calculates the pressure
|
||||||
-- This function combines get_valid_neighbors and get_pressure_straight
|
-- This function combines get_valid_neighbors and get_pressure_straight
|
||||||
|
-- @param b table Buffered LPN
|
||||||
|
-- @param curr table The current LPN
|
||||||
|
-- @return float Pressure of curr calculated from valid neighbors
|
||||||
local function get_valid_neigbor_pressure(b, curr)
|
local function get_valid_neigbor_pressure(b, curr)
|
||||||
local number_of_neighbors = 0
|
local number_of_neighbors = 0
|
||||||
local total_liquid_level = curr.liquid_level
|
local total_liquid_level = curr.liquid_level
|
||||||
@ -123,6 +103,11 @@ local function get_valid_neigbor_pressure(b, curr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Gets the pressure of curr from the neighbors given
|
-- Gets the pressure of curr from the neighbors given
|
||||||
|
-- @param b table Buffered LPN
|
||||||
|
-- @param neighbors table Table of neighboring LPN
|
||||||
|
-- @param number_of_neighbors number Number of neighbors
|
||||||
|
-- @param curr table The current LPN
|
||||||
|
-- @return float Pressure of curr calculated from neighbors
|
||||||
local function get_pressure_straight(b, neighbors, number_of_neighbors, curr)
|
local function get_pressure_straight(b, neighbors, number_of_neighbors, curr)
|
||||||
local total_liquid_level = curr.liquid_level
|
local total_liquid_level = curr.liquid_level
|
||||||
|
|
||||||
@ -133,8 +118,11 @@ local function get_pressure_straight(b, neighbors, number_of_neighbors, curr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Tries to move amount from "from" to "to"
|
-- Tries to move amount from "from" to "to"
|
||||||
--
|
-- Actual amount moved may not be the same as "amount"
|
||||||
--Returns amount moved
|
-- therefore the actual amount moved is returned
|
||||||
|
-- @param from table LPN from which amount is deducted
|
||||||
|
-- @param to table LPN to which amount is added
|
||||||
|
-- @return number Actual amount moved
|
||||||
local function try_move(from, to, amount)
|
local function try_move(from, to, amount)
|
||||||
if to.liquid_level >= 8 then
|
if to.liquid_level >= 8 then
|
||||||
return 0
|
return 0
|
||||||
@ -142,8 +130,8 @@ local function try_move(from, to, amount)
|
|||||||
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)
|
||||||
|
|
||||||
set_lpn(from.liquid_id, from, from.liquid_level - max_allowed_clamped)
|
internal.set_lpn(from.liquid_id, from, from.liquid_level - max_allowed_clamped)
|
||||||
set_lpn(from.liquid_id, to, to.liquid_level + max_allowed_clamped)
|
internal.set_lpn(from.liquid_id, to, to.liquid_level + max_allowed_clamped)
|
||||||
|
|
||||||
if max_allowed_clamped ~= amount then
|
if max_allowed_clamped ~= amount then
|
||||||
return max_allowed_clamped
|
return max_allowed_clamped
|
||||||
@ -151,7 +139,9 @@ local function try_move(from, to, amount)
|
|||||||
return amount
|
return amount
|
||||||
end
|
end
|
||||||
|
|
||||||
--Moves curr_pos
|
-- Calculates how to move curr_pos
|
||||||
|
-- @param b table Buffered LPN
|
||||||
|
-- @param curr_pos table Current position
|
||||||
local function move(b, curr_pos)
|
local function move(b, curr_pos)
|
||||||
local curr_nbs
|
local curr_nbs
|
||||||
local curr_nnbs
|
local curr_nnbs
|
||||||
@ -162,7 +152,7 @@ local function move(b, curr_pos)
|
|||||||
local curr_lpn = get_lpn_buffered(b, curr_pos)
|
local curr_lpn = get_lpn_buffered(b, curr_pos)
|
||||||
|
|
||||||
if curr_lpn.liquid_level <= 0 then
|
if curr_lpn.liquid_level <= 0 then
|
||||||
remove_node_to_check(curr_lpn.pos)
|
internal.remove_node_to_check(curr_lpn.pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -173,14 +163,14 @@ local function move(b, curr_pos)
|
|||||||
if moved > 0 then
|
if moved > 0 then
|
||||||
up_lpn = get_lpn_buffered(b, { x = curr_pos.x, y = curr_pos.y + 1, z = curr_pos.z })
|
up_lpn = get_lpn_buffered(b, { x = curr_pos.x, y = curr_pos.y + 1, z = curr_pos.z })
|
||||||
if up_lpn.liquid_level >= 0 then
|
if up_lpn.liquid_level >= 0 then
|
||||||
add_node_to_check(up_lpn.pos)
|
internal.add_node_to_check(up_lpn.pos)
|
||||||
end
|
end
|
||||||
add_node_to_check(down_lpn.pos)
|
internal.add_node_to_check(down_lpn.pos)
|
||||||
end
|
end
|
||||||
if moved == curr_lpn.liquid_level then
|
if moved == curr_lpn.liquid_level then
|
||||||
remove_node_to_check(curr_lpn.pos)
|
internal.remove_node_to_check(curr_lpn.pos)
|
||||||
for i = 1, curr_nnbs do
|
for i = 1, curr_nnbs do
|
||||||
add_node_to_check(curr_nbs[i].pos)
|
internal.add_node_to_check(curr_nbs[i].pos)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -188,14 +178,14 @@ local function move(b, curr_pos)
|
|||||||
|
|
||||||
-- Every neighbor will be higher (except for air) so processing is done
|
-- Every neighbor will be higher (except for air) so processing is done
|
||||||
if curr_lpn.liquid_level <= 1 then
|
if curr_lpn.liquid_level <= 1 then
|
||||||
remove_node_to_check(curr_lpn.pos)
|
internal.remove_node_to_check(curr_lpn.pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local curr_prs = get_pressure_straight(b, curr_nbs, curr_nnbs, curr_lpn)
|
local curr_prs = get_pressure_straight(b, curr_nbs, curr_nnbs, curr_lpn)
|
||||||
|
|
||||||
if curr_prs >= 4.8 then --4.8 == ((8*4/2)+8)/5 -> meaning maximum pressure, implies no way to move
|
if curr_prs >= 4.8 then --4.8 == ((8*4/2)+8)/5 -> meaning maximum pressure, implies no way to move
|
||||||
remove_node_to_check(curr_lpn.pos)
|
internal.remove_node_to_check(curr_lpn.pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -206,68 +196,36 @@ local function move(b, curr_pos)
|
|||||||
local next_prs = get_valid_neigbor_pressure(b, next_lpn)
|
local next_prs = get_valid_neigbor_pressure(b, next_lpn)
|
||||||
if curr_prs > next_prs and next_lpn.liquid_level < curr_lpn.liquid_level then
|
if curr_prs > next_prs and next_lpn.liquid_level < curr_lpn.liquid_level then
|
||||||
if try_move(curr_lpn, next_lpn, 1) > 0 then
|
if try_move(curr_lpn, next_lpn, 1) > 0 then
|
||||||
add_node_to_check(next_lpn.pos)
|
internal.add_node_to_check(next_lpn.pos)
|
||||||
add_node_to_check(get_lpn_buffered(b, { x = curr_pos.x, y = curr_pos.y + 1, z = curr_pos.z }).pos)
|
internal.add_node_to_check(
|
||||||
|
get_lpn_buffered(b, { x = curr_pos.x, y = curr_pos.y + 1, z = curr_pos.z }).pos
|
||||||
|
)
|
||||||
number_of_swaps = number_of_swaps + 1
|
number_of_swaps = number_of_swaps + 1
|
||||||
end
|
end
|
||||||
elseif curr_lpn.liquid_level < next_lpn.liquid_level then
|
elseif curr_lpn.liquid_level < next_lpn.liquid_level then
|
||||||
add_node_to_check(next_lpn.pos)
|
internal.add_node_to_check(next_lpn.pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if number_of_swaps == 0 then
|
if number_of_swaps == 0 then
|
||||||
remove_node_to_check(curr_lpn.pos)
|
internal.remove_node_to_check(curr_lpn.pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Get placed liquids
|
|
||||||
core.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
|
|
||||||
if liquid_physics.get_liquid_id(core.get_node(pos).name) ~= nil then
|
|
||||||
add_node_to_check(pos)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
--Remove "air" from registered_liquids for lbm and abm
|
|
||||||
local source_names = {}
|
|
||||||
for key, value in pairs(liquid_physics.registered_liquids) do
|
|
||||||
for i = 2, table.getn(value) do
|
|
||||||
table.insert(source_names, value[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
core.register_lbm {
|
|
||||||
name = "liquid_physics:update",
|
|
||||||
nodenames = source_names,
|
|
||||||
run_at_every_load = true,
|
|
||||||
action = function(pos, node, dtime_s)
|
|
||||||
add_node_to_check(pos)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
core.register_abm({
|
|
||||||
nodenames = source_names,
|
|
||||||
neighbors = { "air" },
|
|
||||||
interval = 0.2,
|
|
||||||
chance = 0,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
add_node_to_check(pos)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
core.register_on_mapblocks_changed(function(modified_blocks, modified_blocks_count)
|
core.register_on_mapblocks_changed(function(modified_blocks, modified_blocks_count)
|
||||||
--Buffer
|
-- Buffered LPN
|
||||||
local b = {}
|
local b = {}
|
||||||
for hpos, pos in pairs(nodes_to_check) do
|
for hpos, pos in pairs(liquid_physics._nodes_to_check) do
|
||||||
if core.compare_block_status(pos, "active") then
|
if core.compare_block_status(pos, "active") then
|
||||||
move(b, pos)
|
move(b, pos)
|
||||||
else
|
else
|
||||||
remove_node_to_check(pos)
|
internal.remove_node_to_check(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Update only changed nodes from buffer
|
-- Update only changed nodes from buffer
|
||||||
for _, lpn in pairs(b) do
|
for _, lpn in pairs(b) do
|
||||||
if lpn.init_liquid_level ~= lpn.liquid_level then
|
if lpn.init_liquid_level ~= lpn.liquid_level then
|
||||||
core.set_node(lpn.pos, { name = liquid_physics.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) })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user