Add Bucket Support
This commit is contained in:
parent
2d6c43e69f
commit
ed7e26fb8a
19
api.lua
19
api.lua
@ -15,6 +15,7 @@
|
||||
|
||||
local modpath = core.get_modpath(core.get_current_modname())
|
||||
local internal = dofile(modpath .. "/internal.lua")
|
||||
local internal_bucket = dofile(modpath .. "/bucket.lua")
|
||||
|
||||
-- Returns liquid_id of the node or
|
||||
-- nil when the node is not a liquid
|
||||
@ -64,10 +65,18 @@ function liquid_physics.set_liquid_at(pos, liquid_id, liquid_level)
|
||||
end
|
||||
local lpn = internal.new_lpn(core.hash_node_position(pos), pos)
|
||||
internal.set_lpn(liquid_id, lpn, liquid_level)
|
||||
internal.set_node(lpn)
|
||||
internal.add_node_to_check(pos)
|
||||
return true
|
||||
end
|
||||
|
||||
-- This function will override the bucket provided to add the capapability
|
||||
-- of transporting liquids of factional size
|
||||
-- @param name string Name of the bucket, e.g. "bucket:bucket:water"
|
||||
function liquid_physics.register_bucket(name)
|
||||
internal_bucket.register_filled_bucket(name)
|
||||
end
|
||||
|
||||
-- Executing this function will override the nodes specified.
|
||||
-- New liquid sources will be "liquid_physics:namespace_name_level_1" through 7
|
||||
-- @param namespace string Name of mod e.g. "default"
|
||||
@ -97,6 +106,7 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
||||
|
||||
--Overwrite source
|
||||
source_liquid_def.liquid_range = 0
|
||||
source_liquid_def.groups.liquid_physics = 1
|
||||
|
||||
core.register_node(":" .. source_liquid_name, source_liquid_def)
|
||||
liquid_physics._liquid_ids[source_liquid_name] = id
|
||||
@ -148,14 +158,17 @@ function liquid_physics.register_liquid(namespace, source_name, flowing_name)
|
||||
liquid_physics._liquid_ids[node_name] = id
|
||||
|
||||
table.insert(liquids, node_name)
|
||||
table.insert(liquid_physics._liquids, node_name)
|
||||
end
|
||||
|
||||
table.insert(liquids, source_liquid_name)
|
||||
table.insert(liquid_physics._liquids, source_liquid_name)
|
||||
|
||||
-- Finally, stop flowing
|
||||
core.override_item(flowing_liquid_name, { liquid_range = 0, liquid_renewable = false }, nil)
|
||||
flowing_liquid_def.groups.liquid_physics = 1
|
||||
core.override_item(flowing_liquid_name, {
|
||||
liquid_range = 0,
|
||||
liquid_renewable = false,
|
||||
groups = flowing_liquid_def.groups
|
||||
}, nil)
|
||||
liquid_physics._liquid_ids[flowing_liquid_name] = id
|
||||
|
||||
liquid_physics._registered_liquids[id] = liquids
|
||||
|
281
bucket.lua
Normal file
281
bucket.lua
Normal file
@ -0,0 +1,281 @@
|
||||
local internal_bucket = {}
|
||||
|
||||
local wear_levels = {}
|
||||
wear_levels[1] = 65535
|
||||
wear_levels[2] = 57337
|
||||
wear_levels[3] = 49146
|
||||
wear_levels[4] = 40955
|
||||
wear_levels[5] = 32764
|
||||
wear_levels[6] = 24573
|
||||
wear_levels[7] = 16382
|
||||
wear_levels[8] = 8191
|
||||
wear_levels[9] = 0
|
||||
|
||||
local base_mcl_buckets = core.get_modpath("mcl_buckets")
|
||||
local base_default = core.get_modpath("default")
|
||||
|
||||
local function check_protection(pos, name, text)
|
||||
if core.is_protected(pos, name) then
|
||||
core.log("action", (name ~= "" and name or "A mod")
|
||||
.. " tried to " .. text
|
||||
.. " at protected position "
|
||||
.. core.pos_to_string(pos)
|
||||
.. " with a bucket")
|
||||
core.record_protection_violation(pos, name)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function internal_bucket.get_wear(liquid_level)
|
||||
return wear_levels[liquid_level + 1]
|
||||
end
|
||||
|
||||
function internal_bucket.get_liquid_level(wear)
|
||||
for i = 1, 9 do
|
||||
if wear_levels[i] == wear then
|
||||
return i - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_bucket_item_liquid_level(item, liquid_level)
|
||||
local meta = item:get_meta()
|
||||
|
||||
meta:set_string("description",
|
||||
ItemStack(item:get_name()):get_description() .. " " .. liquid_level .. "/8")
|
||||
|
||||
item:set_wear(internal_bucket.get_wear(liquid_level))
|
||||
end
|
||||
|
||||
local function mcl_get_pointed_thing(usr)
|
||||
local start = usr:get_pos()
|
||||
start.y = start.y + usr:get_properties().eye_height
|
||||
local look_dir = usr:get_look_dir()
|
||||
local _end = vector.add(start, vector.multiply(look_dir, 5))
|
||||
|
||||
local ray = core.raycast(start, _end, false, true)
|
||||
for pointed_thing in ray do
|
||||
local name = core.get_node(pointed_thing.under).name
|
||||
local def = core.registered_nodes[name]
|
||||
if not def or def.drawtype ~= "flowingliquid" then
|
||||
return pointed_thing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_bucket_name_empty()
|
||||
if base_default then
|
||||
return "bucket:bucket_empty"
|
||||
elseif base_mcl_buckets then
|
||||
return "mcl_buckets:bucket_empty"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function get_bucket_name_filled(source_name)
|
||||
if base_default then
|
||||
return bucket.liquids[source_name].itemname
|
||||
elseif base_mcl_buckets then
|
||||
return mcl_buckets.liquids[source_name].bucketname
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function get_liquid_name(bucket_name)
|
||||
if base_default then
|
||||
for source, b in pairs(bucket.liquids) do
|
||||
if b.itemname and b.itemname == bucket_name then
|
||||
return b.source
|
||||
end
|
||||
end
|
||||
elseif base_mcl_buckets then
|
||||
return mcl_buckets.buckets[bucket_name].source_place
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function bucket_on_use(on_use_fallback, itemstack, user, pointed_thing)
|
||||
if pointed_thing.type == "object" then
|
||||
pointed_thing.ref:punch(user, 1.0, { full_punch_interval = 1.0 }, nil)
|
||||
return user:get_wielded_item()
|
||||
elseif pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local liquid = liquid_physics.get_liquid_at(pointed_thing.under)
|
||||
|
||||
if liquid == nil then
|
||||
return on_use_fallback(itemstack, user, pointed_thing)
|
||||
end
|
||||
|
||||
local node = core.get_node(pointed_thing.under)
|
||||
|
||||
if check_protection(pointed_thing.under,
|
||||
user:get_player_name(),
|
||||
"take " .. node.name) then
|
||||
return
|
||||
end
|
||||
|
||||
local liquid_source = liquid_physics.get_liquid_node_names(liquid.liquid_id)[8]
|
||||
local bucket_name = get_bucket_name_filled(liquid_source)
|
||||
|
||||
if bucket_name == nil then
|
||||
return on_use_fallback(itemstack, user, pointed_thing)
|
||||
end
|
||||
|
||||
-- Filled Bucket
|
||||
local bucket_item = ItemStack(bucket_name)
|
||||
set_bucket_item_liquid_level(bucket_item, liquid.liquid_level)
|
||||
|
||||
local return_item = bucket_item
|
||||
|
||||
local item_count = user:get_wielded_item():get_count()
|
||||
|
||||
if item_count > 1 then
|
||||
local inv = user:get_inventory()
|
||||
if inv:room_for_item("main", { name = bucket_name }) then
|
||||
inv:add_item("main", bucket_item)
|
||||
else
|
||||
local pos = user:getpos()
|
||||
pos.y = math.floor(pos.y + 0.5)
|
||||
core.add_item(pos, bucket_item)
|
||||
end
|
||||
|
||||
-- set to return empty buckets minus 1
|
||||
return_item = ItemStack(get_bucket_name_empty() .. tostring(item_count - 1))
|
||||
end
|
||||
|
||||
liquid_physics.set_liquid_at(pointed_thing.under, 0, 0)
|
||||
|
||||
return return_item
|
||||
end
|
||||
|
||||
local function bucket_on_place(on_place_fallback, bucket_liquid_id, source_name, itemstack, user, pointed_thing)
|
||||
-- Must be pointing to node
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local node = core.get_node(pointed_thing.under)
|
||||
local node_def = core.registered_nodes[node.name]
|
||||
|
||||
if not node_def then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
if node_def.on_rightclick and
|
||||
not (user and user:is_player() and
|
||||
user:get_player_control().sneak) then
|
||||
return node_def.on_rightclick(
|
||||
pointed_thing.under,
|
||||
node, user,
|
||||
itemstack)
|
||||
end
|
||||
|
||||
-- Where to place the liquid at
|
||||
local place_at_pos
|
||||
|
||||
if node_def.buildable_to then
|
||||
place_at_pos = pointed_thing.under
|
||||
else
|
||||
place_at_pos = pointed_thing.above
|
||||
|
||||
node = core.get_node(place_at_pos)
|
||||
|
||||
local node_above_def = core.registered_nodes[node.name]
|
||||
|
||||
if not node_above_def or not node_above_def.buildable_to then
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
if check_protection(place_at_pos, user
|
||||
and user:get_player_name()
|
||||
or "", "place " .. source_name) then
|
||||
return
|
||||
end
|
||||
|
||||
local liquid_level = internal_bucket.get_liquid_level(itemstack:get_wear())
|
||||
local liquid = liquid_physics.get_liquid_at(place_at_pos)
|
||||
|
||||
if liquid == nil then
|
||||
if liquid_physics.set_liquid_at(place_at_pos, bucket_liquid_id, liquid_level) then
|
||||
return ItemStack(get_bucket_name_empty())
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
if liquid.liquid_id == bucket_liquid_id then
|
||||
local give_amount = math.min(8 - liquid.liquid_level, liquid_level)
|
||||
if liquid_physics.set_liquid_at(place_at_pos, bucket_liquid_id, liquid.liquid_level + give_amount) then
|
||||
if give_amount == liquid_level then
|
||||
return ItemStack(get_bucket_name_empty())
|
||||
end
|
||||
set_bucket_item_liquid_level(itemstack, liquid_level - give_amount)
|
||||
return itemstack
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
function internal_bucket.register_empty_bucket(bucket_name)
|
||||
local bucket_tool = core.registered_items[bucket_name]
|
||||
|
||||
if base_default then
|
||||
local on_use_fallback = bucket_tool.on_use
|
||||
local on_use_wrapper = function(itemstack, user, pointed_thing)
|
||||
return bucket_on_use(on_use_fallback, itemstack, user, pointed_thing)
|
||||
end
|
||||
core.override_item(bucket_name, { on_use = on_use_wrapper }, nil)
|
||||
elseif base_mcl_buckets then
|
||||
local on_use_fallback = bucket_tool.on_place
|
||||
local on_use_wrapper = function(itemstack, user, pointed_thing)
|
||||
local use_select_box = core.settings:get_bool("mcl_buckets_use_select_box", false)
|
||||
if use_select_box == false then
|
||||
-- TODO: Understand why this is nil
|
||||
if user.get_pos == nil then
|
||||
return itemstack
|
||||
end
|
||||
pointed_thing = mcl_get_pointed_thing(user)
|
||||
end
|
||||
return bucket_on_use(on_use_fallback, itemstack, user, pointed_thing)
|
||||
end
|
||||
core.override_item(bucket_name, { on_place = on_use_wrapper }, nil)
|
||||
end
|
||||
end
|
||||
|
||||
function internal_bucket.register_filled_bucket(name)
|
||||
local bucket_tool = core.registered_items[name]
|
||||
|
||||
local source_name = get_liquid_name(name)
|
||||
if source_name == nil then
|
||||
error("Liquid Physics: Could not register bucket. Liquid for bucket " .. name .. " was not found")
|
||||
end
|
||||
local bucket_liquid_id = liquid_physics.get_liquid_id(source_name)
|
||||
if bucket_liquid_id == nil then
|
||||
error("Liquid Physics: Could not register bucket. Liquid " ..
|
||||
source_name .. " was not registered with liquid physics.")
|
||||
end
|
||||
|
||||
if base_default then
|
||||
local on_place_fallback = bucket_tool.on_place
|
||||
local on_place_wrapper = function(itemstack, user, pointed_thing)
|
||||
return bucket_on_place(on_place_fallback, bucket_liquid_id, source_name, itemstack, user, pointed_thing)
|
||||
end
|
||||
core.override_item(name, {
|
||||
on_place = on_place_wrapper
|
||||
}, nil)
|
||||
elseif base_mcl_buckets then
|
||||
local on_place_fallback = bucket_tool.on_place
|
||||
local on_place_wrapper = function(itemstack, user, pointed_thing)
|
||||
return bucket_on_place(on_place_fallback, bucket_liquid_id, source_name, itemstack, user, pointed_thing)
|
||||
end
|
||||
core.override_item(name, {
|
||||
on_place = on_place_wrapper
|
||||
}, nil)
|
||||
end
|
||||
end
|
||||
|
||||
return internal_bucket
|
15
game/default.lua
Normal file
15
game/default.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local modpath = core.get_modpath(core.get_current_modname())
|
||||
local internal_bucket = dofile(modpath .. "/bucket.lua")
|
||||
|
||||
internal_bucket.register_empty_bucket("bucket:bucket_empty")
|
||||
|
||||
-- Settings
|
||||
|
||||
if core.settings:get_bool("liquid_physics_enable_water_physics", false) then
|
||||
liquid_physics.register_liquid("default", "water_source", "water_flowing")
|
||||
internal_bucket.register_filled_bucket("bucket:bucket_water")
|
||||
end
|
||||
if core.settings:get_bool("liquid_physics_enable_lava_physics", false) then
|
||||
liquid_physics.register_liquid("default", "lava_source", "lava_flowing")
|
||||
internal_bucket.register_filled_bucket("bucket:bucket_lava")
|
||||
end
|
15
game/voxelibre.lua
Normal file
15
game/voxelibre.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local modpath = core.get_modpath(core.get_current_modname())
|
||||
local internal_bucket = dofile(modpath .. "/bucket.lua")
|
||||
|
||||
internal_bucket.register_empty_bucket("mcl_buckets:bucket_empty")
|
||||
|
||||
-- Settings
|
||||
|
||||
if core.settings:get_bool("liquid_physics_enable_water_physics", false) then
|
||||
liquid_physics.register_liquid("mcl_core", "water_source", "water_flowing")
|
||||
internal_bucket.register_filled_bucket("mcl_buckets:bucket_water")
|
||||
end
|
||||
if core.settings:get_bool("liquid_physics_enable_lava_physics", false) then
|
||||
liquid_physics.register_liquid("mcl_core", "lava_source", "lava_flowing")
|
||||
internal_bucket.register_filled_bucket("mcl_buckets:bucket_lava")
|
||||
end
|
20
init.lua
20
init.lua
@ -23,29 +23,19 @@ liquid_physics._nodes_to_check = {}
|
||||
liquid_physics._registered_liquids = {}
|
||||
-- INTERNAL USE ONLY - Stores all liquid node names and their corresponding liquid_id
|
||||
liquid_physics._liquid_ids = {}
|
||||
-- INTERNAL USE ONLY - All liquid nodes for ABM and LBM
|
||||
liquid_physics._liquids = {}
|
||||
|
||||
local internal = dofile(modpath .. "/internal.lua")
|
||||
|
||||
dofile(modpath .. "/api.lua")
|
||||
|
||||
local namespace = ""
|
||||
|
||||
if core.get_modpath("default") then
|
||||
namespace = "default"
|
||||
dofile(modpath .. "/game/default.lua")
|
||||
elseif core.get_modpath("mcl_core") then
|
||||
namespace = "mcl_core"
|
||||
dofile(modpath .. "/game/voxelibre.lua")
|
||||
else
|
||||
error("Liquid Physics only supports VoxeLibre or Minetest")
|
||||
end
|
||||
|
||||
if core.settings:get_bool("liquid_physics_enable_water_physics") then
|
||||
liquid_physics.register_liquid(namespace, "water_source", "water_flowing")
|
||||
end
|
||||
if minetest.settings:get_bool("liquid_physics_enable_lava_physics") then
|
||||
liquid_physics.register_liquid(namespace, "lava_source", "lava_flowing")
|
||||
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)
|
||||
@ -54,7 +44,7 @@ end)
|
||||
|
||||
core.register_lbm {
|
||||
name = "liquid_physics:update",
|
||||
nodenames = liquid_physics._liquids,
|
||||
nodenames = "group:liquid_physics",
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node, dtime_s)
|
||||
internal.add_node_to_check(pos)
|
||||
@ -62,7 +52,7 @@ core.register_lbm {
|
||||
}
|
||||
|
||||
core.register_abm({
|
||||
nodenames = liquid_physics._liquids,
|
||||
nodenames = "group:liquid_physics",
|
||||
neighbors = { "air" },
|
||||
interval = 0.2,
|
||||
chance = 0,
|
||||
|
@ -96,6 +96,12 @@ function internal.set_lpn(liquid_id, lpn, liquid_level)
|
||||
lpn.liquid_id = liquid_id
|
||||
end
|
||||
|
||||
-- Sets liquid node from LPN
|
||||
-- @param lpn table Liquid Physics Node
|
||||
function internal.set_node(lpn)
|
||||
core.set_node(lpn.pos, { name = internal.get_liquid_node_name(lpn.liquid_id, lpn.liquid_level) })
|
||||
end
|
||||
|
||||
-- This node will be checked in the next cycle
|
||||
-- @param pos table Position of the node
|
||||
function internal.add_node_to_check(pos)
|
||||
|
2
mod.conf
2
mod.conf
@ -1,6 +1,6 @@
|
||||
name = liquid_physics
|
||||
depends =
|
||||
optional_depends = default, mcl_core
|
||||
optional_depends = default, mcl_core, bucket, mcl_buckets
|
||||
author = snoutie
|
||||
description = Adds physics to liquids
|
||||
title = Liquid Physics
|
||||
|
@ -225,7 +225,7 @@ core.register_on_mapblocks_changed(function(modified_blocks, modified_blocks_cou
|
||||
-- Update only changed nodes from buffer
|
||||
for _, lpn in pairs(b) do
|
||||
if lpn.init_liquid_level ~= lpn.liquid_level then
|
||||
core.set_node(lpn.pos, { name = internal.get_liquid_node_name(lpn.liquid_id, lpn.liquid_level) })
|
||||
internal.set_node(lpn)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user