359c625df8
This restores an old visual scale from the extremely early days of NodeCore. That style was removed to syncrhonize the scale of stack nodes with item ents. The syncrhonization can work the other way, too, though. This was triggered by wanting to make loose item ents more visually distinct at a glance from settled stack nodes, by making loose item ent rotation faster. Since we were going to change the properties either way, given that, then we might as well use the better visual. Since making stack nodes have a full-size collision hull, it was distracting having the items inside be so mismatched in scale. Also, the "pointing around stacks" thing becomes less important in long-run gameplay with shelves in play, which do not allow pointing around/through anyway.
191 lines
5.7 KiB
Lua
191 lines
5.7 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ItemStack, math, minetest, nodecore, setmetatable, type, vector
|
|
= ItemStack, math, minetest, nodecore, setmetatable, type, vector
|
|
local math_random
|
|
= math.random
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
minetest.register_node(modname .. ":stack", {
|
|
drawtype = "nodebox",
|
|
node_box = nodecore.fixedbox(
|
|
{-0.5, -0.5, -0.5, 0.5, -7/16, 0.5}
|
|
),
|
|
use_texture_alpha = true,
|
|
tiles = {
|
|
"nc_items_shadow.png",
|
|
"nc_items_blank.png",
|
|
},
|
|
walkable = true,
|
|
selection_box = nodecore.fixedbox(
|
|
{-0.4, -0.5, -0.4, 0.4, 0.3, 0.4}
|
|
),
|
|
collision_box = nodecore.fixedbox(),
|
|
drop = {},
|
|
groups = {
|
|
snappy = 1,
|
|
falling_repose = 1,
|
|
visinv = 1,
|
|
is_stack_only = 1
|
|
},
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
repose_drop = function(posfrom, posto, node)
|
|
local stack = nodecore.stack_get(posfrom)
|
|
if stack and not stack:is_empty() then
|
|
nodecore.item_eject(posto, stack)
|
|
end
|
|
return minetest.remove_node(posfrom)
|
|
end,
|
|
on_rightclick = function(pos, node, whom, stack, pointed, ...)
|
|
if not nodecore.interact(whom) then return stack end
|
|
local def = nodecore.stack_get(pos):get_definition() or {}
|
|
if def.stack_rightclick then
|
|
local rtn = def.stack_rightclick(pos, node, whom, stack, pointed, ...)
|
|
if rtn then return rtn end
|
|
end
|
|
return nodecore.stack_add(pos, stack)
|
|
end,
|
|
on_construct = function(pos, ...)
|
|
minetest.after(0, function()
|
|
return nodecore.stack_sounds(pos, "place")
|
|
end)
|
|
return nodecore.visinv_on_construct(pos, ...)
|
|
end
|
|
})
|
|
|
|
function nodecore.place_stack(pos, stack, placer, pointed_thing)
|
|
stack = ItemStack(stack)
|
|
local name = stack:get_name()
|
|
|
|
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
|
if nodecore.match(below, {name = name, count = false}) then
|
|
stack = nodecore.stack_add(below, stack)
|
|
if stack:is_empty() then return end
|
|
end
|
|
|
|
minetest.set_node(pos, {name = modname .. ":stack"})
|
|
nodecore.stack_set(pos, stack)
|
|
if placer and pointed_thing then
|
|
nodecore.craft_check(pos, {name = stack:get_name()}, {
|
|
action = "place",
|
|
crafter = placer,
|
|
pointed = pointed_thing
|
|
})
|
|
end
|
|
|
|
return minetest.check_for_falling(pos)
|
|
end
|
|
|
|
local bii = minetest.registered_entities["__builtin:item"]
|
|
local item = {
|
|
on_step = function(self, dtime, ...)
|
|
bii.on_step(self, dtime, ...)
|
|
|
|
local pos = self.object:getpos()
|
|
if not self.oldpos or not vector.equals(pos, self.oldpos) then
|
|
self.oldpos = pos
|
|
self.sitting = 0
|
|
return
|
|
end
|
|
self.sitting = (self.sitting or 0) + dtime
|
|
if self.sitting < 0.25 then return end
|
|
|
|
pos = vector.round(pos)
|
|
local i = ItemStack(self.itemstring)
|
|
pos = nodecore.scan_flood(pos, 5,
|
|
function(p)
|
|
if p.y > pos.y and math_random() < 0.95 then return end
|
|
if p.y > pos.y + 1 then return end
|
|
i = nodecore.stack_add(p, i)
|
|
if i:is_empty() then return p end
|
|
if nodecore.buildable_to(p) then return p end
|
|
end)
|
|
if not pos then return end
|
|
if not i:is_empty() then nodecore.place_stack(pos, i) end
|
|
self.itemstring = ""
|
|
self.object:remove()
|
|
end,
|
|
on_punch = function(self, whom, ...)
|
|
if not nodecore.interact(whom) then return end
|
|
local r = bii.on_punch(self, whom, ...)
|
|
if self.itemstring ~= "" then
|
|
local v = self.object:get_velocity()
|
|
v.x = v.x + math_random() * 5 - 2.5
|
|
v.y = v.y + math_random() * 5 - 2.5
|
|
v.z = v.z + math_random() * 5 - 2.5
|
|
self.object:set_velocity(v)
|
|
end
|
|
end
|
|
}
|
|
setmetatable(item, bii)
|
|
minetest.register_entity(":__builtin:item", item)
|
|
|
|
local bifn = minetest.registered_entities["__builtin:falling_node"]
|
|
local falling = {
|
|
set_node = function(self, node, meta, ...)
|
|
if node and node.name == modname .. ":stack"
|
|
and meta and meta.inventory and meta.inventory.solo then
|
|
local stack = ItemStack(meta.inventory.solo[1] or "")
|
|
if not stack:is_empty() then
|
|
nodecore.item_eject(self.object:getpos(), stack,
|
|
nil, nil, {x = 0, y = 0.01, z = 0})
|
|
return self.object:remove()
|
|
end
|
|
end
|
|
return bifn.set_node(self, node, meta, ...)
|
|
end
|
|
}
|
|
setmetatable(falling, bifn)
|
|
minetest.register_entity(":__builtin:falling_node", falling)
|
|
|
|
function minetest.item_place(itemstack, placer, pointed_thing, param2)
|
|
if not nodecore.interact(placer) then return end
|
|
if pointed_thing.type == "node" and placer and
|
|
not placer:get_player_control().sneak then
|
|
local n = minetest.get_node(pointed_thing.under)
|
|
local nn = n.name
|
|
local nd = minetest.registered_items[nn]
|
|
if nd and nd.on_rightclick then
|
|
return nd.on_rightclick(pointed_thing.under, n,
|
|
placer, itemstack, pointed_thing) or itemstack, false
|
|
end
|
|
end
|
|
local def = itemstack:get_definition()
|
|
if def.type == "node" and not def.place_as_item then
|
|
return minetest.item_place_node(itemstack, placer, pointed_thing, param2)
|
|
end
|
|
if not itemstack:is_empty() then
|
|
local above = minetest.get_pointed_thing_position(pointed_thing, true)
|
|
if above and nodecore.buildable_to(above) then
|
|
nodecore.place_stack(above, itemstack:take_item(), placer, pointed_thing)
|
|
end
|
|
end
|
|
return itemstack
|
|
end
|
|
|
|
if nodecore.loaded_mods().nc_fire then
|
|
nodecore.register_limited_abm({
|
|
label = "Flammable ItemStacks Ignite",
|
|
interval = 5,
|
|
chance = 1,
|
|
nodenames = {modname .. ":stack"},
|
|
neighbors = {"group:igniter"},
|
|
action = function(pos, node)
|
|
if nodecore.quenched(pos) then return end
|
|
|
|
local stack = nodecore.stack_get(pos)
|
|
if not stack or stack:is_empty() then return end
|
|
local def = minetest.registered_items[stack:get_name()] or {}
|
|
local flam = def.groups and def.groups.flammable
|
|
if not flam then return end
|
|
|
|
if math_random(1, flam) ~= 1 then return end
|
|
nodecore.ignite(pos, node)
|
|
end
|
|
})
|
|
end
|
|
|
|
nodecore.register_cook_abm({nodenames = {modname .. ":stack"}})
|