2018-11-02 21:20:51 -04:00
|
|
|
-- LUALOCALS < ---------------------------------------------------------
|
2019-02-09 22:44:56 -05:00
|
|
|
local ItemStack, math, minetest, nodecore, setmetatable, type, vector
|
|
|
|
= ItemStack, math, minetest, nodecore, setmetatable, type, vector
|
2019-01-26 12:50:06 -05:00
|
|
|
local math_random
|
2019-01-30 21:02:19 -05:00
|
|
|
= math.random
|
2018-11-02 21:20:51 -04:00
|
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
|
2018-10-30 10:18:49 -04:00
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
|
|
|
|
minetest.register_node(modname .. ":stack", {
|
2019-01-06 18:46:00 -05:00
|
|
|
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",
|
|
|
|
},
|
2018-10-30 10:18:49 -04:00
|
|
|
walkable = true,
|
2019-03-22 18:41:33 -04:00
|
|
|
selection_box = nodecore.fixedbox(
|
Larger, bolder, easier to see item and stack ents.
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.
2019-03-30 22:07:23 -04:00
|
|
|
{-0.4, -0.5, -0.4, 0.4, 0.3, 0.4}
|
2019-03-22 18:41:33 -04:00
|
|
|
),
|
Larger, bolder, easier to see item and stack ents.
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.
2019-03-30 22:07:23 -04:00
|
|
|
collision_box = nodecore.fixedbox(),
|
2018-10-30 19:54:28 -04:00
|
|
|
drop = {},
|
2018-10-30 10:18:49 -04:00
|
|
|
groups = {
|
2019-01-24 22:08:05 -05:00
|
|
|
snappy = 1,
|
2018-11-03 08:46:14 -04:00
|
|
|
falling_repose = 1,
|
2019-02-23 02:29:16 -05:00
|
|
|
visinv = 1,
|
|
|
|
is_stack_only = 1
|
2018-10-30 10:18:49 -04:00
|
|
|
},
|
|
|
|
paramtype = "light",
|
2018-10-30 11:12:36 -04:00
|
|
|
sunlight_propagates = true,
|
2018-11-02 07:52:23 -04:00
|
|
|
repose_drop = function(posfrom, posto, node)
|
2019-02-23 10:21:27 -05:00
|
|
|
local stack = nodecore.stack_get(posfrom)
|
2018-11-02 07:52:23 -04:00
|
|
|
if stack and not stack:is_empty() then
|
2019-01-25 09:26:15 -05:00
|
|
|
nodecore.item_eject(posto, stack)
|
2018-11-02 07:52:23 -04:00
|
|
|
end
|
|
|
|
return minetest.remove_node(posfrom)
|
2018-12-30 19:37:59 -05:00
|
|
|
end,
|
2019-01-29 20:41:29 -05:00
|
|
|
on_rightclick = function(pos, node, whom, stack, pointed, ...)
|
2019-02-24 21:54:33 -05:00
|
|
|
if not nodecore.interact(whom) then return stack end
|
2019-03-23 16:56:02 -04:00
|
|
|
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
|
2019-02-23 10:21:27 -05:00
|
|
|
return nodecore.stack_add(pos, stack)
|
2019-03-14 00:31:09 -04:00
|
|
|
end,
|
|
|
|
on_construct = function(pos, ...)
|
|
|
|
minetest.after(0, function()
|
|
|
|
return nodecore.stack_sounds(pos, "place")
|
|
|
|
end)
|
|
|
|
return nodecore.visinv_on_construct(pos, ...)
|
2019-01-29 20:41:29 -05:00
|
|
|
end
|
2018-10-30 10:18:49 -04:00
|
|
|
})
|
|
|
|
|
2019-01-03 23:42:53 -05:00
|
|
|
function nodecore.place_stack(pos, stack, placer, pointed_thing)
|
|
|
|
stack = ItemStack(stack)
|
|
|
|
local name = stack:get_name()
|
2019-01-29 23:12:07 -05:00
|
|
|
|
2019-01-29 20:41:29 -05:00
|
|
|
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
2019-02-27 23:12:19 -05:00
|
|
|
if nodecore.match(below, {name = name, count = false}) then
|
|
|
|
stack = nodecore.stack_add(below, stack)
|
|
|
|
if stack:is_empty() then return end
|
|
|
|
end
|
2019-01-29 23:12:07 -05:00
|
|
|
|
2019-01-26 16:14:01 -05:00
|
|
|
minetest.set_node(pos, {name = modname .. ":stack"})
|
2019-02-23 10:21:27 -05:00
|
|
|
nodecore.stack_set(pos, stack)
|
2019-01-03 23:42:53 -05:00
|
|
|
if placer and pointed_thing then
|
2019-02-03 12:10:27 -05:00
|
|
|
nodecore.craft_check(pos, {name = stack:get_name()}, {
|
|
|
|
action = "place",
|
|
|
|
crafter = placer,
|
|
|
|
pointed = pointed_thing
|
|
|
|
})
|
2019-01-03 23:42:53 -05:00
|
|
|
end
|
2019-02-28 23:47:36 -05:00
|
|
|
|
2019-04-05 07:42:48 -04:00
|
|
|
return minetest.after(0, function() minetest.check_for_falling(pos) end)
|
2019-01-03 23:42:53 -05:00
|
|
|
end
|
|
|
|
|
2018-10-30 10:18:49 -04:00
|
|
|
local bii = minetest.registered_entities["__builtin:item"]
|
|
|
|
local item = {
|
2019-02-19 00:34:12 -05:00
|
|
|
on_step = function(self, dtime, ...)
|
|
|
|
bii.on_step(self, dtime, ...)
|
|
|
|
|
2019-04-06 20:34:13 -04:00
|
|
|
local pos = self.object:get_pos()
|
2019-02-19 00:34:12 -05:00
|
|
|
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)
|
2019-01-25 01:15:14 -05:00
|
|
|
local i = ItemStack(self.itemstring)
|
2019-01-24 23:34:08 -05:00
|
|
|
pos = nodecore.scan_flood(pos, 5,
|
|
|
|
function(p)
|
2019-03-06 22:07:18 -05:00
|
|
|
if p.y > pos.y and math_random() < 0.95 then return end
|
2019-03-05 23:18:09 -05:00
|
|
|
if p.y > pos.y + 1 then return end
|
2019-02-23 10:21:27 -05:00
|
|
|
i = nodecore.stack_add(p, i)
|
2019-01-25 01:15:14 -05:00
|
|
|
if i:is_empty() then return p end
|
|
|
|
if nodecore.buildable_to(p) then return p end
|
2019-01-24 23:34:08 -05:00
|
|
|
end)
|
2018-11-02 22:00:39 -04:00
|
|
|
if not pos then return end
|
2019-01-25 01:15:14 -05:00
|
|
|
if not i:is_empty() then nodecore.place_stack(pos, i) end
|
2018-10-30 10:18:49 -04:00
|
|
|
self.itemstring = ""
|
|
|
|
self.object:remove()
|
|
|
|
end,
|
2019-02-24 21:54:33 -05:00
|
|
|
on_punch = function(self, whom, ...)
|
|
|
|
if not nodecore.interact(whom) then return end
|
|
|
|
local r = bii.on_punch(self, whom, ...)
|
2019-02-19 00:34:12 -05:00
|
|
|
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
|
2019-01-26 12:50:06 -05:00
|
|
|
end
|
2018-10-30 10:18:49 -04:00
|
|
|
}
|
|
|
|
setmetatable(item, bii)
|
2018-10-30 19:54:28 -04:00
|
|
|
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
|
2019-04-14 01:33:50 -04:00
|
|
|
local ent = minetest.add_item(self.object:get_pos(), stack)
|
|
|
|
if ent then ent:set_velocity({x = 0, y = 0, z = 0}) end
|
2018-10-30 19:54:28 -04:00
|
|
|
return self.object:remove()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return bifn.set_node(self, node, meta, ...)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
setmetatable(falling, bifn)
|
2018-11-02 21:20:51 -04:00
|
|
|
minetest.register_entity(":__builtin:falling_node", falling)
|
2019-01-03 23:42:53 -05:00
|
|
|
|
|
|
|
function minetest.item_place(itemstack, placer, pointed_thing, param2)
|
2019-02-24 21:54:33 -05:00
|
|
|
if not nodecore.interact(placer) then return end
|
2019-01-03 23:42:53 -05:00
|
|
|
if pointed_thing.type == "node" and placer and
|
|
|
|
not placer:get_player_control().sneak then
|
2019-01-03 23:52:05 -05:00
|
|
|
local n = minetest.get_node(pointed_thing.under)
|
2019-01-03 23:42:53 -05:00
|
|
|
local nn = n.name
|
2019-03-13 23:51:59 -04:00
|
|
|
local nd = minetest.registered_items[nn]
|
|
|
|
if nd and nd.on_rightclick then
|
|
|
|
return nd.on_rightclick(pointed_thing.under, n,
|
2019-01-03 23:42:53 -05:00
|
|
|
placer, itemstack, pointed_thing) or itemstack, false
|
|
|
|
end
|
|
|
|
end
|
2019-03-23 13:01:31 -04:00
|
|
|
local def = itemstack:get_definition()
|
|
|
|
if def.type == "node" and not def.place_as_item then
|
2019-01-03 23:42:53 -05:00
|
|
|
return minetest.item_place_node(itemstack, placer, pointed_thing, param2)
|
|
|
|
end
|
2019-01-03 23:54:49 -05:00
|
|
|
if not itemstack:is_empty() then
|
2019-01-04 20:11:04 -05:00
|
|
|
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
|
2019-01-03 23:54:49 -05:00
|
|
|
end
|
2019-01-03 23:42:53 -05:00
|
|
|
return itemstack
|
|
|
|
end
|
2019-02-10 12:16:00 -05:00
|
|
|
|
|
|
|
if nodecore.loaded_mods().nc_fire then
|
|
|
|
nodecore.register_limited_abm({
|
2019-02-19 00:34:12 -05:00
|
|
|
label = "Flammable ItemStacks Ignite",
|
|
|
|
interval = 5,
|
|
|
|
chance = 1,
|
|
|
|
nodenames = {modname .. ":stack"},
|
|
|
|
neighbors = {"group:igniter"},
|
|
|
|
action = function(pos, node)
|
2019-03-11 23:52:18 -04:00
|
|
|
local stack = nodecore.stack_get(pos)
|
2019-03-31 20:54:38 -04:00
|
|
|
return nodecore.fire_check_ignite(pos, {name = stack:get_name()})
|
2019-02-19 00:34:12 -05:00
|
|
|
end
|
|
|
|
})
|
|
|
|
end
|
2019-03-22 22:55:30 -04:00
|
|
|
|
|
|
|
nodecore.register_cook_abm({nodenames = {modname .. ":stack"}})
|
2019-04-05 07:42:48 -04:00
|
|
|
|
|
|
|
if minetest.raycast then
|
|
|
|
local olddrop = minetest.item_drop
|
|
|
|
function minetest.item_drop(item, player, ...)
|
|
|
|
local oldadd = minetest.add_item
|
|
|
|
function minetest.add_item(pos, stack, ...)
|
|
|
|
if not minetest.raycast then
|
|
|
|
return oldadd(pos, stack, ...)
|
|
|
|
end
|
|
|
|
|
|
|
|
local start = player:get_pos()
|
|
|
|
local eyeheight = player:get_properties().eye_height or 1.625
|
|
|
|
start.y = start.y + eyeheight
|
|
|
|
local target = vector.add(start, vector.multiply(player:get_look_dir(), 4))
|
|
|
|
local pointed = minetest.raycast(start, target, false)()
|
|
|
|
if (not pointed) or pointed.type ~= "node" then
|
|
|
|
return oldadd(pos, stack, ...)
|
|
|
|
end
|
|
|
|
|
|
|
|
local dummyent = {}
|
|
|
|
setmetatable(dummyent, {__index = function(t, k)
|
|
|
|
return function() return {} end
|
|
|
|
end})
|
|
|
|
|
|
|
|
local name = stack:get_name()
|
|
|
|
local function tryplace(p)
|
|
|
|
if nodecore.match(p, {name = name, count = false}) then
|
|
|
|
stack = nodecore.stack_add(p, stack)
|
|
|
|
if stack:is_empty() then return dummyent end
|
|
|
|
end
|
|
|
|
if nodecore.buildable_to(p) then
|
|
|
|
nodecore.place_stack(p, stack, player, pointed)
|
|
|
|
return dummyent
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return tryplace(pointed.under)
|
|
|
|
or tryplace(pointed.above)
|
|
|
|
or oldadd(pos, stack, ...)
|
|
|
|
end
|
|
|
|
local function helper(...)
|
|
|
|
minetest.add_item = oldadd
|
|
|
|
return ...
|
|
|
|
end
|
|
|
|
return helper(olddrop(item, player, ...))
|
|
|
|
end
|
|
|
|
end
|