diff options
Diffstat (limited to 'init.lua')
-rwxr-xr-x[-rw-r--r--] | init.lua | 398 |
1 files changed, 18 insertions, 380 deletions
@@ -2,7 +2,6 @@ Minetest Mod Storage Drawers - A Mod adding storage drawers Copyright (C) 2017 LNJ <git@lnj.li> -Copyright (C) 2016 Mango Tango <mtango688@gmail.com> MIT License @@ -27,396 +26,35 @@ SOFTWARE. drawers = {} -local WOOD_SOUNDS -local WOOD_ITEMSTRING -local CHEST_ITEMSTRING if default then - WOOD_SOUNDS = default.node_sound_wood_defaults() - WOOD_ITEMSTRING = "default:wood" - CHEST_ITEMSTRING = "default:chest" + drawers.WOOD_SOUNDS = default.node_sound_wood_defaults() + drawers.WOOD_ITEMSTRING = "default:wood" + drawers.CHEST_ITEMSTRING = "default:chest" elseif mcl_core then -- MineClone 2 - WOOD_ITEMSTRING = "mcl_core:wood" - CHEST_ITEMSTRING = "mcl_chests:chest" + drawers.WOOD_ITEMSTRING = "mcl_core:wood" + drawers.CHEST_ITEMSTRING = "mcl_chests:chest" if mcl_sounds then - WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults() + drawers.WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults() end else - WOOD_ITEMSTRING = "wood" - CHEST_ITEMSTRING = "chest" + drawers.WOOD_ITEMSTRING = "wood" + drawers.CHEST_ITEMSTRING = "chest" end -local DEFAULT_VISUAL_TEXTURE = "drawers_empty.png" -drawers.node_box_simple = { - {-0.5, -0.5, -0.4375, 0.5, 0.5, 0.5}, - {-0.5, -0.5, -0.5, -0.4375, 0.5, -0.4375}, - {0.4375, -0.5, -0.5, 0.5, 0.5, -0.4375}, - {-0.4375, 0.4375, -0.5, 0.4375, 0.5, -0.4375}, - {-0.4375, -0.5, -0.5, 0.4375, -0.4375, -0.4375}, -} +-- +-- Load files +-- -local function gen_info_text(basename, count, factor, stack_max) - -- in the end it should look like: - -- Sand [4x99+43 / 24x99] - -- bot NOT so: - -- Dirt [2x99 + 0 / 24x99] - local countstr = tostring(math.floor(count / stack_max)) .. "x" .. - stack_max - if count % stack_max ~= 0 then - countstr = countstr .. " + " .. count % stack_max - end - return basename .. " [" .. countstr .. " / " .. factor .. "x" .. stack_max .. "]" -end - -local function get_inv_image(name) - local texture = DEFAULT_VISUAL_TEXTURE - local def = core.registered_items[name] - if name ~= "air" and def then - if def.inventory_image and #def.inventory_image > 0 then - texture = def.inventory_image - else - if not def.tiles then return texture end - - local c = #def.tiles or 0 - local x = {} - for i, v in ipairs(def.tiles) do - if type(v) == "table" then - x[i] = v.name - else - x[i] = v - end - i = i + 1 - end - if not x[3] then x[3] = x[1] end - if not x[4] then x[4] = x[3] end - texture = core.inventorycube(x[1], x[3], x[4]) - end - end - return texture -end - -core.register_entity("drawers:visual", { - initial_properties = { - hp_max = 1, - physical = false, - collide_with_objects = false, - collisionbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0}, -- for param2 0, 2 - visual = "upright_sprite", -- "wielditem" for items without inv img? - visual_size = {x = 0.6, y = 0.6}, - textures = {"drawers_empty.png"}, - spritediv = {x = 1, y = 1}, - initial_sprite_basepos = {x = 0, y = 0}, - is_visible = true, - }, - - get_staticdata = function(self) - return core.serialize({ - drawer_posx = self.drawer_pos.x, - drawer_posy = self.drawer_pos.y, - drawer_posz = self.drawer_pos.z, - texture = self.texture - }) - end, - - on_activate = function(self, staticdata, dtime_s) - -- Restore data - data = core.deserialize(staticdata) - if data then - self.drawer_pos = { - x = data.drawer_posx, - y = data.drawer_posy, - z = data.drawer_posz, - } - self.texture = data.texture - else - self.drawer_pos = drawers.last_drawer_pos - self.texture = drawers.last_texture or DEFAULT_VISUAL_TEXTURE - end - - - local node = core.get_node(self.drawer_pos) - - -- collisionbox - local colbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0} -- for param2 = 0 or 2 - if node.param2 == 1 or node.param2 == 3 then - colbox = {0, -0.4374, -0.4374, 0, 0.4374, 0.4374} - end - - - -- infotext - local meta = core.get_meta(self.drawer_pos) - local infotext = meta:get_string("entity_infotext") .. "\n\n\n\n\n" - - self.object:set_properties({ - collisionbox = colbox, - infotext = infotext, - textures = {self.texture} - }) - - -- make entity undestroyable - self.object:set_armor_groups({immortal = 1}) - end, - - on_rightclick = function(self, clicker) - local node = core.get_node(self.drawer_pos) - local itemstack = clicker:get_wielded_item() - local add_count = itemstack:get_count() - local add_name = itemstack:get_name() - - local meta = core.get_meta(self.drawer_pos) - local name = meta:get_string("name") - local count = meta:get_int("count") - local max_count = meta:get_int("max_count") - - local base_stack_max = meta:get_int("base_stack_max") - local stack_max_factor = meta:get_int("stack_max_factor") - - -- if nothing to be added, return - if add_count <= 0 then return end - -- if no itemstring, return - if item_name == "" then return end - - -- only add one, if player holding sneak key - if clicker:get_player_control().sneak then - add_count = 1 - end - - -- if current itemstring is not empty - if name ~= "" then - -- check if same item - if add_name ~= name then return end - else -- is empty - name = add_name - count = 0 - - -- get new stack max - base_stack_max = ItemStack(name):get_stack_max() - max_count = base_stack_max * stack_max_factor - - -- Don't add items stackable only to 1 - if base_stack_max == 1 then - return - end - - meta:set_string("name", name) - meta:set_int("base_stack_max", base_stack_max) - meta:set_int("max_count", max_count) - end - - -- set new counts: - -- if new count is more than max_count - if (count + add_count) > max_count then - count = max_count - itemstack:set_count((count + add_count) - max_count) - else -- new count fits - count = count + add_count - itemstack:set_count(itemstack:get_count() - add_count) - end - -- set new drawer count - meta:set_int("count", count) - - -- update infotext - local infotext = gen_info_text(core.registered_items[name].description, - count, stack_max_factor, base_stack_max) - meta:set_string("entity_infotext", infotext) - - -- texture - self.texture = get_inv_image(name) - - self.object:set_properties({ - infotext = infotext .. "\n\n\n\n\n", - textures = {self.texture} - }) - - clicker:set_wielded_item(itemstack) - end, - - on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) - local meta = minetest.get_meta(self.drawer_pos) - local count = meta:get_int("count") - - if count <= 0 then - return - end - local name = meta:get_string("name") - - local remove_count = 1 - if not puncher:get_player_control().sneak then - remove_count = ItemStack(name):get_stack_max() - end - if remove_count > count then remove_count = count end - - local stack = ItemStack(name) - stack:set_count(remove_count) - - local inv = puncher:get_inventory() - if not inv:room_for_item("main", stack) then - return - end - - inv:add_item("main", stack) - count = count - remove_count - meta:set_int("count", count) - - -- update infotext - local stack_max_factor = meta:get_int("stack_max_factor") - local base_stack_max = meta:get_int("base_stack_max") - local item_description = "" - if core.registered_items[name] then - item_description = core.registered_items[name].description - end +local modpath = core.get_modpath("drawers") +dofile(modpath .. "/lua/helpers.lua") +dofile(modpath .. "/lua/visual.lua") +dofile(modpath .. "/lua/api.lua") - if count <= 0 then - meta:set_string("name", "") - self.texture = "drawers_empty.png" - item_description = "Empty" - end - local infotext = gen_info_text(item_description, - count, stack_max_factor, base_stack_max) - meta:set_string("entity_infotext", infotext) - - self.object:set_properties({ - infotext = infotext .. "\n\n\n\n\n", - textures = {self.texture} - }) - end -}) - -local function spawn_visual(pos) - local node = core.get_node(pos) - - -- data for the new visual - drawers.last_drawer_pos = pos - drawers.last_texture = get_inv_image(core.get_meta(pos):get_string("name")) - - local bdir = core.facedir_to_dir(node.param2) - local fdir = vector.new(-bdir.x, 0, -bdir.z) - local pos2 = vector.add(pos, vector.multiply(fdir, 0.438)) - - obj = core.add_entity(pos2, "drawers:visual") - - if bdir.x < 0 then obj:setyaw(0.5 * math.pi) end - if bdir.z < 0 then obj:setyaw(math.pi) end - if bdir.x > 0 then obj:setyaw(1.5 * math.pi) end - - drawers.last_texture = nil -end - --- construct drawer -local function drawer_on_construct(pos) - local node = core.get_node(pos) - local ndef = core.registered_nodes[node.name] - - local base_stack_max = core.nodedef_default.stack_max or 99 - local stack_max_factor = ndef.drawer_stack_max_factor or 24 -- 3x8 - - -- meta - local meta = core.get_meta(pos) - meta:set_string("name", "") - meta:set_int("count", 0) - meta:set_int("max_count", base_stack_max * stack_max_factor) - meta:set_int("stack_max_factor", stack_max_factor) - meta:set_int("base_stack_max", base_stack_max) - meta:set_string("entity_infotext", gen_info_text("Empty", 0, - stack_max_factor, base_stack_max)) - - spawn_visual(pos) -end - --- destruct drawer -local function drawer_on_destruct(pos) - local objs = core.get_objects_inside_radius(pos, 0.5) - if objs then - for _, obj in pairs(objs) do - if obj and obj:get_luaentity() and - obj:get_luaentity().name == "drawers:visual" then - obj:remove() - return - end - end - end -end - --- drop all items -local function drawer_on_dig(pos, node, player) - local meta = core.get_meta(pos) - local count = meta:get_int("count") - local name = meta:get_string("name") - - -- remove node - core.node_dig(pos, node, player) - - -- drop the items - local stack_max = ItemStack(name):get_stack_max() - - local j = math.floor(count / stack_max) + 1 - local i = 1 - while i <= j do - if not (i == j) then - core.add_item(pos, name .. " " .. stack_max) - else - core.add_item(pos, name .. " " .. count % stack_max) - end - i = i + 1 - end -end - -core.register_lbm({ - name = "drawers:restore_visual", - nodenames = {"group:drawer"}, - run_at_every_load = true, - action = function(pos, node) - local objs = core.get_objects_inside_radius(pos, 0.5) - if objs then - for _, obj in pairs(objs) do - if obj and obj:get_luaentity() and - obj:get_luaentity().name == "drawers:visual" then - return - end - end - end - - -- no visual found, create a new one - spawn_visual(pos) - end -}) - -function drawers.register_drawer(name, def) - def.description = def.description or "Drawer" - def.drawtype = "nodebox" - def.node_box = {type = "fixed", fixed = drawers.node_box_simple} - def.collision_box = {type = "regular"} - def.selection_box = {type = "regular"} - def.paramtype = "light" - def.paramtype2 = "facedir" - def.legacy_facedir_simple = true - def.groups = def.groups or {} - def.groups.drawer = def.groups.drawer or 1 - def.drawer_stack_max_factor = def.drawer_stack_max_factor or 24 - - -- events - def.on_construct = drawer_on_construct - def.on_destruct = drawer_on_destruct - def.on_dig = drawer_on_dig - - if screwdriver then - def.on_rotate = def.on_rotate or screwdriver.disallow - end - - core.register_node(name, def) - - if (not def.no_craft) and def.material then - core.register_craft({ - output = name, - recipe = { - {def.material, def.material, def.material}, - {"", CHEST_ITEMSTRING, ""}, - {def.material, def.material, def.material} - } - }) - end -end +-- +-- Register drawers +-- drawers.register_drawer("drawers:wood", { description = "Wooden Drawer", |