-- LUALOCALS < --------------------------------------------------------- local ItemStack, ipairs, minetest, nodecore, pairs, type = ItemStack, ipairs, minetest, nodecore, pairs, type -- LUALOCALS > --------------------------------------------------------- nodecore.amcoremod() local modname = minetest.get_current_modname() local metadescs = { "Tote (1 Slot)", "Tote (2 Slots)", "Tote (3 Slots)", "Tote (4 Slots)", "Tote (5 Slots)", "Tote (6 Slots)", "Tote (7 Slots)", "Tote (8 Slots)", } local function totedug(pos, _, _, digger) local drop = ItemStack(modname .. ":handle") if not digger:get_player_control().sneak then local dump for dx = -1, 1 do for dz = -1, 1 do local p = {x = pos.x + dx, y = pos.y, z = pos.z + dz} local n = minetest.get_node(p) local d = minetest.registered_items[n.name] or {} if d and d.groups and d.groups.totable then local m = minetest.get_meta(p):to_table() for _, v1 in pairs(m.inventory or {}) do for k2, v2 in pairs(v1) do if type(v2) == "userdata" then v1[k2] = v2:to_string() end end end dump = dump or {} dump[#dump + 1] = { x = dx, z = dz, n = n, m = m } minetest.remove_node(p) end end end if dump then local meta = drop:get_meta() meta:set_string("carrying", minetest.serialize(dump)) meta:set_string("description", metadescs[#dump]) drop:set_name(modname .. ":handle_full") end end minetest.handle_node_drops(pos, {drop}, digger) end local function toteplace(stack, _, pointed) local pos = nodecore.buildable_to(pointed.under) and pointed.under or nodecore.buildable_to(pointed.above) and pointed.above if not pos then return stack end stack = ItemStack(stack) local inv = stack:get_meta():get_string("carrying") inv = inv and (inv ~= "") and minetest.deserialize(inv) if not inv then minetest.set_node(pos, {name = stack:get_name()}) stack:set_count(stack:get_count() - 1) return stack end local commit = {{pos, {name = modname .. ":handle"}, {}}} for _, v in ipairs(inv) do if commit then local p = {x = pos.x + v.x, y = pos.y, z = pos.z + v.z} if (not nodecore.buildable_to(p)) or nodecore.obstructed(p) then commit = nil else commit[#commit + 1] = {p, v.n, v.m} end end end if commit then for _, v in ipairs(commit) do minetest.set_node(v[1], v[2]) minetest.get_meta(v[1]):from_table(v[3]) end stack:set_count(stack:get_count() - 1) end return stack end local function tote_ignite(pos) local stack = nodecore.stack_get(pos) if minetest.get_item_group(stack:get_name(), "tote") < 1 then return true end local stackmeta = stack:get_meta() local raw = stackmeta:get_string("carrying") local inv = raw and (raw ~= "") and minetest.deserialize(raw) if not inv then return true end local newinv = {} for _, slot in pairs(inv) do local nn = slot and slot.n and slot.n.name local flam = minetest.get_item_group(nn, "flammable") if flam > 0 then nodecore.item_eject(pos, nn) for _, list in pairs(slot and slot.m and slot.m.inventory or {}) do for _, item in pairs(list) do local istack = ItemStack(item) if not istack:is_empty() then nodecore.item_eject(pos, istack) end end end else newinv[#newinv + 1] = slot end end local newraw = minetest.serialize(newinv) if newraw == raw then return true end stackmeta:set_string("carrying", newraw) stackmeta:set_string("description", metadescs[#newinv]) stack:set_name(modname .. ":handle" .. ((#newinv > 0) and "_full" or "")) nodecore.stack_set(pos, stack) return true end local txr_bot = "nc_lode_annealed.png" local txr_sides = "(" .. txr_bot .. "^[mask:nc_tote_sides.png)" local txr_top = "nc_tree_tree_side.png^[mask:nc_tote_top.png^[transformR90^" .. txr_sides local txr_handle = "nc_tree_tree_side.png^[transformR90" local function reg(suff, inner) return minetest.register_node(modname .. ":handle" .. suff, { description = "Tote Handle", meta_descriptions = metadescs, drawtype = "mesh", visual_scale = nodecore.z_fight_ratio, mesh = "nc_tote_handle.obj", selection_box = nodecore.fixedbox(), paramtype = "light", tiles = { {name = txr_sides, backface_culling = true}, {name = txr_bot, backface_culling = true}, {name = txr_top, backface_culling = true}, {name = txr_handle, backface_culling = true}, {name = inner, backface_culling = true} }, groups = { snappy = 1, container = 100, flammable = 5, tote = 1 }, on_ignite = tote_ignite, stack_max = 1, after_dig_node = totedug, on_place = toteplace, drop = "", sounds = nodecore.sounds("nc_lode_annealed") }) end reg("", "[combine:1x1") reg("_full", modname .. "_fill.png") nodecore.register_craft({ label = "craft tote handle", norotate = true, nodes = { {match = "nc_woodwork:frame", replace = "air"}, {y = -1, match = "nc_lode:block_annealed", replace = modname .. ":handle"}, {y = -1, x = 1, match = {groups = {totable = true}}}, {y = -1, x = -1, match = {groups = {totable = true}}}, {y = -1, z = 1, match = {groups = {totable = true}}}, {y = -1, z = -1, match = {groups = {totable = true}}}, } }) nodecore.register_craft({ label = "break apart tote", action = "pummel", toolgroups = {choppy = 5}, check = function(pos, data) if data.node.name == modname .. ":handle" then return true end local stack = nodecore.stack_get(pos) if stack:get_name() ~= modname .. ":handle" then return end return (stack:get_meta():get_string("carrying") or "") == "" end, nodes = { { match = modname .. ":handle", replace = "air" } }, items = { {name = "nc_lode:prill_annealed 2", count = 4, scatter = 5} } }) nodecore.register_aism({ label = "Packed Tote AISMs", interval = 1, chance = 1, itemnames = {modname .. ":handle"}, action = function(stack, data) local stackmeta = stack:get_meta() local raw = stackmeta:get_string("carrying") local inv = raw and (raw ~= "") and minetest.deserialize(raw) if not inv then return end local dirty for _, slot in pairs(inv) do for lname, list in pairs(slot and slot.m and slot.m.inventory or {}) do for sub, item in pairs(list) do local istack = ItemStack(item) local sdata = { pos = data.pos, toteslot = slot, totelistname = lname, totelist = list, totesubslot = sub, set = function(s) list[sub] = s:to_string() dirty = true end } if not istack:is_empty() then nodecore.aism_check_stack(istack, sdata) end end end end if not dirty then return end stackmeta:set_string("carrying", minetest.serialize(inv)) return stack end })