Finished Soaking API, converted trees and infusion to it.
This commit is contained in:
parent
253ccad3e2
commit
cbf035e0d5
@ -21,7 +21,6 @@ ISSUES: Bugs, Cleanup and Refinements
|
||||
- Do nothing after return; callback responsible
|
||||
for all transformations.
|
||||
- Uses:
|
||||
- Tree growth.
|
||||
- Lux infusion.
|
||||
- Fallen leaves + grass + sunlight decay to nothing.
|
||||
- Fallen leaves buried in leaves decay to dirt.
|
||||
|
@ -58,6 +58,7 @@ include("match")
|
||||
include("fx_digparticles")
|
||||
|
||||
include("register_limited_abm")
|
||||
include("register_soaking_abm")
|
||||
include("register_ambiance")
|
||||
include("mapgen_shared")
|
||||
|
||||
|
75
mods/nc_api/register_soaking_abm.lua
Normal file
75
mods/nc_api/register_soaking_abm.lua
Normal file
@ -0,0 +1,75 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local error, math, minetest, nodecore, type
|
||||
= error, math, minetest, nodecore, type
|
||||
local math_floor, math_sqrt
|
||||
= math.floor, math.sqrt
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
function nodecore.register_soaking_abm(def)
|
||||
def.qtyfield = def.qtyfield or "soakqty"
|
||||
def.timefield = def.timefield or "soaktime"
|
||||
|
||||
def.soakinterval = def.soakinterval or ((def.interval or 1) * (def.chance or 1))
|
||||
|
||||
if not def.soakrate then error("soaking abm missing soakrate callback") end
|
||||
if not def.soakcheck then error("soaking abm missing soakcheck callback") end
|
||||
|
||||
def.soakvary = def.soakvary or 0.25
|
||||
if not def.soakrand then
|
||||
if def.soakvary then
|
||||
def.soakrand = function(rate, ticks)
|
||||
return rate * (1 + def.soakvary * nodecore.boxmuller()
|
||||
/ math_sqrt(ticks)) * ticks
|
||||
end
|
||||
else
|
||||
def.soakrand = function(rate, ticks) return rate * ticks end
|
||||
end
|
||||
end
|
||||
|
||||
def.action = function(pos, ...)
|
||||
local now = minetest.get_gametime()
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local total = meta:get_float(def.qtyfield) or 0
|
||||
local start = meta:get_float(def.timefield)
|
||||
start = start and start ~= 0 and start or now
|
||||
|
||||
local rate = 0
|
||||
local delta = 0
|
||||
if start <= now then
|
||||
rate = def.soakrate(pos, ...)
|
||||
if rate == false then
|
||||
minetest.log("soak abm reset at " .. minetest.pos_to_string(pos))
|
||||
meta:set_string(def.qtyfield, "")
|
||||
meta:set_string(def.timefield, "")
|
||||
return
|
||||
end
|
||||
rate = rate or 0
|
||||
local ticks = 1 + math_floor((now - start) / def.soakinterval)
|
||||
delta = def.soakrand(rate, ticks)
|
||||
total = total + delta
|
||||
start = start + ticks * def.soakinterval
|
||||
end
|
||||
|
||||
minetest.log("soak check at " .. minetest.pos_to_string(pos)
|
||||
.. ": " .. minetest.serialize({
|
||||
rate = rate,
|
||||
delta = delta,
|
||||
total = total
|
||||
}))
|
||||
local set = def.soakcheck({
|
||||
rate = rate,
|
||||
delta = delta,
|
||||
total = total
|
||||
}, pos, ...)
|
||||
if set == false then
|
||||
meta:set_string(def.qtyfield, "")
|
||||
meta:set_string(def.timefield, "")
|
||||
return
|
||||
end
|
||||
meta:set_float(def.qtyfield, set and type(set) == "number" and set or total)
|
||||
meta:set_float(def.timefield, start)
|
||||
end
|
||||
|
||||
return nodecore.register_limited_abm(def)
|
||||
end
|
@ -1,8 +1,8 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local ItemStack, ipairs, math, minetest, nodecore, pairs, type, unpack
|
||||
= ItemStack, ipairs, math, minetest, nodecore, pairs, type, unpack
|
||||
local math_random
|
||||
= math.random
|
||||
local math_cos, math_log, math_pi, math_random, math_sin, math_sqrt
|
||||
= math.cos, math.log, math.pi, math.random, math.sin, math.sqrt
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
for k, v in pairs(minetest) do
|
||||
@ -72,6 +72,21 @@ function nodecore.pickrand(tbl, weight)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local saved
|
||||
function nodecore.boxmuller()
|
||||
local old = saved
|
||||
if old then
|
||||
saved = nil
|
||||
return old
|
||||
end
|
||||
local r = math_sqrt(-2 * math_log(math_random()))
|
||||
local t = 2 * math_pi * math_random()
|
||||
saved = r * math_sin(t)
|
||||
return r * math_cos(t)
|
||||
end
|
||||
end
|
||||
|
||||
function nodecore.extend_item(name, func)
|
||||
local orig = minetest.registered_items[name] or {}
|
||||
local copy = {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local ItemStack, math, minetest, nodecore, pairs, vector
|
||||
= ItemStack, math, minetest, nodecore, pairs, vector
|
||||
local math_pow
|
||||
= math.pow
|
||||
local math_floor, math_pow
|
||||
= math.floor, math.pow
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
@ -46,19 +46,19 @@ for _, v in pairs(nodecore.dirs()) do
|
||||
indirs[#indirs + 1] = v
|
||||
end
|
||||
end
|
||||
nodecore.register_limited_abm({
|
||||
nodecore.register_soaking_abm({
|
||||
label = "Lux Infusion",
|
||||
interval = 1,
|
||||
chance = 2,
|
||||
interval = 2,
|
||||
chance = 1,
|
||||
nodenames = {"nc_items:stack"},
|
||||
neighbors = {"group:lux_fluid"},
|
||||
action = function(pos)
|
||||
soakrate = function(pos)
|
||||
local stack = nodecore.stack_get(pos)
|
||||
local name = stack:get_name()
|
||||
if (not charge[name]) and (not convert[name]) then return end
|
||||
if (not charge[name]) and (not convert[name]) then return false end
|
||||
|
||||
local above = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||
if not isfluid(above) then return end
|
||||
if not isfluid(above) then return false end
|
||||
local qty = 1
|
||||
for _, v in pairs(indirs) do
|
||||
if isfluid(vector.add(pos, v)) then qty = qty + 1 end
|
||||
@ -70,15 +70,22 @@ nodecore.register_limited_abm({
|
||||
if nn == modname .. ":flux_source" then return d end
|
||||
if nn ~= modname .. ":flux_flowing" then return false end
|
||||
end)
|
||||
if not dist then return end
|
||||
if not dist then return false end
|
||||
|
||||
return qty * 20 / math_pow(2, dist / 2)
|
||||
end,
|
||||
soakcheck = function(data, pos)
|
||||
local stack = nodecore.stack_get(pos)
|
||||
local name = stack:get_name()
|
||||
local dw = math_floor(data.total)
|
||||
if charge[name] then
|
||||
stack:add_wear(-qty * 20 / math_pow(2, dist / 2))
|
||||
stack:add_wear(-dw)
|
||||
nodecore.stack_set(pos, stack)
|
||||
elseif convert[name] and stack:get_wear() < 3277 then
|
||||
stack = ItemStack(convert[name])
|
||||
stack:set_wear(65535)
|
||||
stack:set_wear(65535 - dw)
|
||||
nodecore.stack_set(pos, stack)
|
||||
end
|
||||
return data.total - dw
|
||||
end
|
||||
})
|
||||
|
@ -1,8 +1,8 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local math, minetest, nodecore
|
||||
= math, minetest, nodecore
|
||||
local math_random, math_sqrt
|
||||
= math.random, math.sqrt
|
||||
local math_sqrt
|
||||
= math.sqrt
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
@ -68,13 +68,14 @@ minetest.register_node(epname, nodecore.underride({
|
||||
},
|
||||
minetest.registered_items[ldname] or {}))
|
||||
|
||||
nodecore.register_limited_abm({
|
||||
nodecore.register_soaking_abm({
|
||||
label = "EggCorn Growing",
|
||||
nodenames = {epname},
|
||||
interval = 10,
|
||||
chance = 1,
|
||||
action = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
qtyfield = "growth",
|
||||
timefield = "start",
|
||||
soakrate = function(pos)
|
||||
local d = 0
|
||||
local w = 1
|
||||
nodecore.scan_flood(pos, 3, function(p)
|
||||
@ -93,11 +94,18 @@ nodecore.register_limited_abm({
|
||||
return false
|
||||
end
|
||||
end)
|
||||
local rate = math_sqrt(d * w)
|
||||
return math_sqrt(d * w)
|
||||
end,
|
||||
soakcheck = function(data, pos)
|
||||
if data.total >= 5000 then
|
||||
local place = {x = pos.x - 2, y = pos.y, z = pos.z - 2}
|
||||
return minetest.place_schematic(place, nodecore.tree_schematic,
|
||||
"random", {}, false)
|
||||
end
|
||||
local zero = {x = 0, y = 0, z = 0}
|
||||
nodecore.digparticles(minetest.registered_items[modname .. ":leaves"],
|
||||
{
|
||||
amount = rate,
|
||||
amount = data.rate,
|
||||
time = 10,
|
||||
minpos = {
|
||||
x = pos.x - 0.3,
|
||||
@ -116,21 +124,5 @@ nodecore.register_limited_abm({
|
||||
minsize = 1,
|
||||
maxsize = 3,
|
||||
})
|
||||
local g = meta:get_float("growth") or 0
|
||||
local now = minetest.get_gametime()
|
||||
local t = meta:get_float("start")
|
||||
t = t and t > 0 and t or now
|
||||
while t <= now do
|
||||
g = g + rate * math_random()
|
||||
t = t + 10
|
||||
end
|
||||
if g >= 5000 then
|
||||
meta:from_table({})
|
||||
local place = {x = pos.x - 2, y = pos.y, z = pos.z - 2}
|
||||
return minetest.place_schematic(place, nodecore.tree_schematic,
|
||||
"random", {}, false)
|
||||
end
|
||||
meta:set_float("growth", g)
|
||||
meta:set_float("start", t)
|
||||
end
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user