diff --git a/cauldron.lua b/cauldron.lua new file mode 100644 index 0000000..5c7afec --- /dev/null +++ b/cauldron.lua @@ -0,0 +1,190 @@ + +local _fldlib = minetest.get_modpath("fluid_lib") ~= nil + +magicalities.cauldron = { + recipes = { + { + items = {"default:coal_lump 9"}, + requirements = { + earth = 5 + }, + output = "default:diamond" + } + } +} + +local function flatten_stacks(stacks) + local temp = {} + for _, stack in pairs(stacks) do + local name = stack:get_name() + if not temp[name] then + temp[name] = stack:get_count() + else + temp[name] = temp[name] + stack:get_count() + end + end + + local stacks_new = {} + for name,count in pairs(temp) do + table.insert(stacks_new, ItemStack(name .. " " .. count)) + end + + return stacks_new +end + +local function get_recipe(items_found, wand) + local match = {} + for _,r in pairs(magicalities.cauldron.recipes) do + local pass = true + for _,item in pairs(r.items) do + local found = false + for _,item2 in pairs(items_found) do + local i1 = ItemStack(item) + local i2 = ItemStack(item2) + if i1:get_name() == i2:get_name() and i2:get_count() >= i1:get_count() then + found = true + break + end + end + if not found then + pass = false + break + end + end + if pass then + table.insert(match,r) + end + end + + if #match == 0 then return nil end + local fulfilled = {} + for _,a in pairs(match) do + if magicalities.wands.wand_has_contents(wand, a.requirements) then + table.insert(fulfilled, a) + end + end + + if #fulfilled == 0 then return nil end + return fulfilled[1] +end + +-- Return a list of items dropped into the cauldron +local function sample_items(pos, pickup) + local items = {} + for _,object in ipairs(minetest.env:get_objects_inside_radius(pos, 1)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + if object:get_luaentity().itemstring ~= "" then + table.insert(items, object:get_luaentity().itemstring) + end + if pickup then + object:get_luaentity().itemstring = "" + object:remove() + end + end + end + if #items == 0 then return nil end + return items +end + +local _clddef = { + description = "Cauldron", + tiles = {"magicalities_cauldron.png"}, + groups = {cracky = 2, cauldron = 1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.4375, -0.4375, -0.4375, 0.4375, -0.3125, 0.4375}, + {-0.375, -0.5, -0.375, -0.25, -0.4375, -0.25}, + {0.25, -0.5, 0.25, 0.375, -0.4375, 0.375}, + {0.25, -0.5, -0.375, 0.375, -0.4375, -0.25}, + {-0.375, -0.5, 0.25, -0.25, -0.4375, 0.375}, + {-0.4375, -0.3125, -0.4375, 0.4375, 0.5, -0.3125}, + {-0.4375, -0.3125, 0.3125, 0.4375, 0.5, 0.4375}, + {-0.4375, -0.3125, -0.3125, -0.3125, 0.5, 0.3125}, + {0.3125, -0.3125, -0.3125, 0.4375, 0.5, 0.3125}, + } + }, + on_construct = function (pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("items", 8) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if node.name ~= "magicalities:cauldron" then return itemstack end + if itemstack:get_name() == "bucket:bucket_water" and not _fldlib then + node.name = "magicalities:cauldron_with_water" + minetest.swap_node(pos, node) + return ItemStack("bucket:bucket_empty") + end + return itemstack + end, + _wand_use = function (pos, node, itemstack, user, pointed_thing) + if not user or user:get_player_name() == "" then return itemstack end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stacks = flatten_stacks(inv:get_list("items")) + local recipe = get_recipe(stacks, itemstack) + + if user:get_player_control().sneak then + inv:set_list("items", {}) + node.name = "magicalities:cauldron" + minetest.swap_node(pos, node) + return itemstack + end + + if not recipe then return itemstack end + + for _,st in pairs(recipe.items) do + for _,sta in pairs(stacks) do + if sta:get_name() == st then + sta:take_item(ItemStack(st):get_count()) + end + end + end + + --inv:set_list("items", stacks) + inv:set_list("items", {}) + node.name = "magicalities:cauldron" + minetest.swap_node(pos, node) + minetest.item_drop(ItemStack(recipe.output), user, user:get_pos()) + itemstack = magicalities.wands.wand_take_contents(itemstack, recipe.requirements) + magicalities.wands.update_wand_desc(itemstack) + + return itemstack + end +} + +local _clddefw = table.copy(_clddef) +_clddefw.groups.not_in_creative_inventory = 1 +_clddefw.drop = "magicalities:cauldron" +_clddefw.tiles = {"magicalities_cauldron_with_water.png", "magicalities_cauldron.png", "magicalities_cauldron.png", + "magicalities_cauldron.png", "magicalities_cauldron.png", "magicalities_cauldron.png"} +table.insert(_clddefw.node_box.fixed, {-0.3125, -0.3125, -0.3125, 0.3125, 0.375, 0.3125}) + +minetest.register_node("magicalities:cauldron", _clddef) +minetest.register_node("magicalities:cauldron_with_water", _clddefw) + +minetest.register_abm({ + label = "Cauldron", + interval = 1, + chance = 1, + --name = "magicalities:cauldron_insert", + nodenames = {"magicalities:cauldron_with_water"}, + neighbors = {"group:igniter"}, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local pickup = sample_items(pos, true) + if not pickup then return end + for _,i in pairs(pickup) do + local stack = ItemStack(i) + if inv:room_for_item("items", stack) then + inv:add_item("items", stack) + else + minetest.item_drop(stack, "", vector.add(pos, {x=0,y=1,z=0})) + end + end + end +}) \ No newline at end of file diff --git a/init.lua b/init.lua index 3ec7005..3d16064 100644 --- a/init.lua +++ b/init.lua @@ -37,5 +37,8 @@ dofile(modpath.."/craftitems.lua") -- Scanner dofile(modpath.."/scanner.lua") +-- Cauldron +dofile(modpath.."/cauldron.lua") + -- Register dofile(modpath.."/register.lua") diff --git a/mod.conf b/mod.conf index 9b448fb..5d850c7 100644 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,4 @@ name = magicalities description = Magic mod. depends = default -optional_depends = craftguide +optional_depends = craftguide,fluid_lib diff --git a/textures/magicalities_cauldron.png b/textures/magicalities_cauldron.png new file mode 100644 index 0000000..26cabea Binary files /dev/null and b/textures/magicalities_cauldron.png differ diff --git a/textures/magicalities_cauldron_with_water.png b/textures/magicalities_cauldron_with_water.png new file mode 100644 index 0000000..8342251 Binary files /dev/null and b/textures/magicalities_cauldron_with_water.png differ diff --git a/wands.lua b/wands.lua index 7fc0a60..fde85b3 100644 --- a/wands.lua +++ b/wands.lua @@ -198,6 +198,7 @@ end local function wand_action(itemstack, placer, pointed_thing) if not pointed_thing.type == "node" then return itemstack end + local pos = pointed_thing.under local node = minetest.get_node(pointed_thing.under) local imeta = itemstack:get_meta() @@ -207,6 +208,16 @@ local function wand_action(itemstack, placer, pointed_thing) magicalities.wands.update_wand_desc(itemstack) end + -- Call rightclick on the wand focus + local focus, fdef = magicalities.wands.get_wand_focus(itemstack) + if focus then + if fdef["_wand_node"] and focus_requirements(itemstack, fdef) then + itemstack = fdef["_wand_node"](pos, node, placer, itemstack, pointed_thing) + + return itemstack + end + end + -- Replacement local to_replace = nil for grp, result in pairs(magicalities.wands.transform_recipes) do @@ -216,14 +227,8 @@ local function wand_action(itemstack, placer, pointed_thing) end end - -- Call rightclick on the wand focus - local focus, fdef = magicalities.wands.get_wand_focus(itemstack) - if focus then - if fdef["_wand_node"] and focus_requirements(itemstack, fdef) then - itemstack = fdef["_wand_node"](pointed_thing.under, node, placer, itemstack, pointed_thing) - - return itemstack - end + if to_replace and minetest.is_protected(pos, placer:get_player_name()) then + to_replace = nil end -- Call on_rightclick on the node instead if it cannot be replaced @@ -231,7 +236,7 @@ local function wand_action(itemstack, placer, pointed_thing) local nodedef = minetest.registered_nodes[node.name] if nodedef.on_rightclick then - itemstack = nodedef.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing) + itemstack = nodedef.on_rightclick(pos, node, placer, itemstack, pointed_thing) end return itemstack @@ -243,11 +248,11 @@ local function wand_action(itemstack, placer, pointed_thing) magicalities.wands.update_wand_desc(itemstack) end - minetest.swap_node(pointed_thing.under, {name = to_replace.result, param1 = node.param1, param2 = node.param2}) + minetest.swap_node(pos, {name = to_replace.result, param1 = node.param1, param2 = node.param2}) local spec = minetest.registered_nodes[to_replace.result] if spec.on_construct then - spec.on_construct(pointed_thing.under) + spec.on_construct(pos) end return itemstack @@ -272,6 +277,16 @@ local function use_wand(itemstack, user, pointed_thing) end end + -- Call use on the node + local pos = pointed_thing.under + local node = minetest.get_node_or_nil(pos) + if node and node.name ~= "air" then + local ndef = minetest.registered_nodes[node.name] + if ndef['_wand_use'] then + return ndef['_wand_use'](pos, node, itemstack, user, pointed_thing) + end + end + magicalities.wands.update_wand_desc(itemstack) return itemstack end