API refinements.

- Make node match operate on only one of node or stack, depending
  on whether node defers to stack via is_stack_only.  This should
  hopefully prevent future pummel recipe issues.
- Add new core stack API.  Needs to be deployed in a lot of places.
- Start work on system for allowing flammable containers; they
  eject their potentially non-flammable contents.
This commit is contained in:
Aaron Suen 2019-02-23 09:44:22 -05:00
parent f02de5719a
commit f893f613c3
8 changed files with 53 additions and 30 deletions

View File

@ -29,6 +29,7 @@ include("util_scan_flood")
include("util_logtrace")
include("util_node_is")
include("util_toolcaps")
include("util_stack")
include("match")
include("fx_digparticles")

View File

@ -18,27 +18,33 @@ function nodecore.match(thing, crit)
if type(crit) == "string" then crit = {name = crit} end
local stack = thing.stack
if stack then
thing.name = stack:get_name()
thing.count = stack:get_count()
thing.wear = stack:get_wear()
end
thing.count = thing.count or 1
if not thing.name then
thing = nodecore.underride(thing, minetest.get_node(thing))
end
local def = minetest.registered_items[thing.name]
if (not thing.stackcheck) and def.groups and def.groups.is_stack_only then
local stack = minetest.get_meta(thing):get_inventory():get_stack("solo", 1)
if stack and not stack:is_empty() then
thing.name = stack:get_name()
def = minetest.registered_items[thing.name]
thing.count = stack:get_count()
thing.wear = stack:get_wear()
end
thing.stackcheck = true
end
if crit.name and thing.name ~= crit.name then return end
if crit.param2 and thing.param2 ~= crit.param2 then return end
if crit.param and thing.param ~= crit.param then return end
if crit.count and thing.count ~= crit.count then return end
if crit.count == nil and thing.count and thing.count ~= 1 then return end
if crit.count == nil and thing.count ~= 1 then return end
if crit.wear then
if crit.wear < 1 then crit.wear = crit.wear * 65535 end
if thing.wear > crit.wear then return end
end
local def = minetest.registered_items[thing.name]
if crit.groups then
if not def or not def.groups then return end
for k, v in pairs(crit.groups) do
@ -57,14 +63,5 @@ function nodecore.match(thing, crit)
end
end
if crit.stack then
local stack = minetest.get_meta(thing):get_inventory():get_stack("solo", 1)
if (not stack) or stack:is_empty() then return end
local copy = {}
for k, v in pairs(thing) do copy[k] = v end
copy.stack = stack
return nodecore.match(copy, crit.stack)
end
return thing
end

View File

@ -0,0 +1,26 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, minetest, nodecore
= ItemStack, minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
function nodecore.node_inv(pos)
return minetest.get_meta(pos):get_inventory()
end
function nodecore.stack_get(pos)
return nodecore.node_inv(pos):get_stack("solo", 1)
end
function nodecore.stack_set(pos, stack)
return nodecore.node_inv(pos):set_stack("solo", 1, ItemStack(stack))
end
function nodecore.stack_add(pos, stack)
return nodecore.node_inv(pos):add_item("solo", ItemStack(stack))
end
function nodecore.stack_giveto(pos, player)
local stack = nodecore.solostack_get(pos)
stack = player:get_inventory():add_item("main", stack)
return nodecore.solostack_set(pos, stack)
end

View File

@ -58,15 +58,6 @@ nodecore.register_limited_abm({
local def = minetest.registered_nodes[node.name]
local flam = def and def.groups and def.groups.flammable
if not flam then return end
if def.groups.visinv then
local stack = minetest.get_meta(pos)
:get_inventory():get_stack("solo", 1)
if stack and not stack:is_empty() then
local idef = minetest.registered_items[stack:get_name()]
flam = idef and idef.groups and idef.groups.flammable
end
end
if not flam then return end
-- Ignite randomly.
if math_random(1, flam) ~= 1 then return end

View File

@ -12,6 +12,14 @@ function nodecore.ignite(pos, node)
if fuel < 0 then fuel = 0 end
if fuel > 6 then fuel = 6 end
fuel = math_floor(fuel)
local stack
if nodecore.node_group("eject_inv_on_burn", pos, node) then
stack = nodecore.stack_get(pos)
if stack and (not stack:is_empty()) then
local p = nodecore.scan_flood(pos, 2, nodecore.buildable_to)
nodecore.item_eject(p or pos, stack, 1)
end
end
minetest.set_node(pos, {name = modname .. ((fuel > 0)
and (":ember" .. fuel) or ":fire")})
minetest.after(0, function() minetest.check_for_falling(pos) end)

View File

@ -137,7 +137,7 @@ nodecore.register_craft({
toolgroups = {thumpy = 3},
nodes = {
{
match = {stack = {name = modname .. ":prill_hot", count = 8}},
match = {name = modname .. ":prill_hot", count = 8},
replace = "air"
}
},

View File

@ -66,8 +66,8 @@ local function forge(from, fromqty, to, prills)
toolgroups = {thumpy = 3},
nodes = {
{
match = {stack = {name = modname .. ":" .. from .. "_annealed",
count = fromqty}},
match = {name = modname .. ":" .. from .. "_annealed",
count = fromqty},
replace = "air"
},
{

View File

@ -28,7 +28,7 @@ nodecore.register_craft({
action = "pummel",
nodes = {
{
match = {stack = {name = modname .. ":chip", count = 8}},
match = {name = modname .. ":chip", count = 8},
replace = "nc_terrain:cobble_loose"
}
},