diff --git a/crafts.lua b/crafts.lua new file mode 100644 index 0000000..8513526 --- /dev/null +++ b/crafts.lua @@ -0,0 +1,247 @@ +minetest.register_craftitem("cooking:sugar", { + description = "Sugar", + inventory_image = "cooking_sugar.png", +}) +cooking.register_craft({ + type = "press", + recipe = "default:papyrus", + output = "cooking:sugar" +}) + +if not foodspoil_register then foodspoil_register = function() end end + +--breads +minetest.register_craftitem("cooking:bun", { + description = "Uncooked Bun", + inventory_image = "cooking_bun_uncooked.png", +}) +minetest.register_craftitem("cooking:bun_cooked", { + description = "Bun", + on_use = minetest.item_eat(4), + inventory_image = "cooking_bun.png", +}) +minetest.register_craftitem("cooking:bread_sliced", { + description = "Sliced Bread", + on_use = minetest.item_eat(3), + inventory_image = "cooking_bread_sliced.png", +}) +minetest.register_craftitem("cooking:toast", { + description = "Toast", + on_use = minetest.item_eat(4), + inventory_image = "cooking_toast.png", +}) +minetest.register_craftitem("cooking:bread_with_jam", { + description = "Bread with Jam", + inventory_image = "cooking_bread_with_jam.png", + on_use = minetest.item_eat(5), +}) +minetest.register_craftitem("cooking:toast_with_jam", { + description = "Toast with Jam", + inventory_image = "cooking_toast_with_jam.png", + on_use = minetest.item_eat(6), +}) +minetest.register_craftitem("cooking:blueberry_jam", { + description = "Blueberry Jam", + inventory_image = "cooking_blueberry_jam.png", +}) +minetest.clear_craft({output = "farming:bread"}) +minetest.clear_craft({output = "farming:flour"}) +cooking.register_craft({ + type = "mix", + recipe = {"farming:wheat", "farming:wheat", "farming:wheat", "bucket:bucket_water", "cooking:sugar"}, + output = "farming:flour,bucket:bucket_empty" +}) +cooking.register_craft({ + type = "oven", + cooktime = 20, + recipe = "farming:flour", + output = "farming:bread" +}) +cooking.register_craft({ + type = "stove", + cooktime = 5, + recipe = "cooking:bread_sliced", + output = "cooking:toast" +}) +cooking.register_craft({ + type = "cut", + recipe = "farming:bread", + output = "cooking:bread_sliced 6" +}) +foodspoil_register("cooking:bread_sliced", 4) +cooking.register_craft({ + type = "stack", + recipe = {"cooking:bread_sliced", "cooking:blueberry_jam"}, + output = "cooking:bread_with_jam" +}) +foodspoil_register("cooking:bread_with_jam", 4) +cooking.register_craft({ + type = "stack", + recipe = {"cooking:toast", "cooking:blueberry_jam"}, + output = "cooking:toast_with_jam" +}) +cooking.register_craft({ + type = "cut", + recipe = "farming:flour", + output = "cooking:bun 4" +}) +cooking.register_craft({ + type = "oven", + cooktime = 10, + recipe = "cooking:bun", + output = "cooking:bun_cooked" +}) + +--apple pie +minetest.register_craftitem("cooking:chopped_apple", { + description = "Chopped Apple", + inventory_image = "cooking_chopped_apple.png", +}) +minetest.register_craftitem("cooking:apple_pie_uncooked", { + description = "Uncooked Apple Pie", + inventory_image = "cooking_apple_pie_uncooked.png", +}) +minetest.register_craftitem("cooking:apple_pie", { + description = "Apple Pie", + inventory_image = "cooking_apple_pie.png", + on_use = minetest.item_eat(10), +}) +minetest.register_craftitem("cooking:pie_crust", { + description = "Pie Crust", + inventory_image = "cooking_pie_crust.png", +}) +cooking.register_craft({ + type = "roll", + recipe = "cooking:bun", + output = "cooking:pie_crust" +}) +cooking.register_craft({ + type = "cut", + recipe = "default:apple", + output = "cooking:chopped_apple" +}) +cooking.register_craft({ + type = "stack", + recipe = {"cooking:pie_crust", "cooking:chopped_apple", "cooking:chopped_apple", "cooking:sugar", "cooking:pie_crust"}, + output = "cooking:apple_pie_uncooked" +}) +cooking.register_craft({ + type = "oven", + cooktime = 30, + recipe = "cooking:apple_pie_uncooked", + output = "cooking:apple_pie" +}) + +--mushroom soup +minetest.register_craftitem("cooking:mushroom_soup_uncooked", { + description = "Uncooked Mushroom Soup", + stack_max = 1, + inventory_image = "cooking_mushroom_soup_uncooked.png", + param2 = 224, + on_use = minetest.item_eat(4, "cooking:bowl") +}) +foodspoil_register("cooking:mushroom_soup_uncooked", 4) +minetest.register_craftitem("cooking:mushroom_soup", { + description = "Mushroom Soup", + stack_max = 1, + inventory_image = "cooking_mushroom_soup.png", + param2 = 222, + on_use = minetest.item_eat(6, "cooking:bowl") +}) +foodspoil_register("cooking:mushroom_soup", 4) +foodspoil_register("cooking:mushroom_soup_uncooked", 4) +cooking.register_craft({ + type = "soup", + param2 = 6, + recipe = {"flowers:mushroom_brown", "flowers:mushroom_brown", "flowers:mushroom_brown"}, + output = "cooking:mushroom_soup_uncooked" +}) +cooking.register_craft({ + type = "stove", + cooktime = 10, + recipe = "cooking:mushroom_soup_uncooked", + output = "cooking:mushroom_soup", + burned = "cooking:burnt_soup" +}) + +--tools +minetest.register_craft({ + recipe = { + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""} + }, + output = "cooking:bowl 4" +}) +minetest.register_craft({ + recipe = { + {"group:wood", "", "group:wood"}, + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""} + }, + output = "cooking:mixing_bowl 2" +}) +minetest.register_craft({ + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + }, + output = "cooking:pot_0 2" +}) +minetest.register_craft({ + recipe = { + {"default:glass", "group:sand", "default:glass"}, + {"", "default:glass", ""} + }, + output = "cooking:plate 4" +}) +minetest.register_craft({ + recipe = { + {"default:stick", "group:wood", "default:stick"}, + }, + output = "cooking:rolling_pin" +}) +minetest.register_craft({ + recipe = { + {"default:stick", "group:wood", "default:stick"}, + }, + output = "cooking:rolling_pin" +}) +minetest.register_craft({ + recipe = { + {"", "group:wood"}, + {"default:stick", ""}, + }, + output = "cooking:spoon" +}) +for i, subname in pairs({"wood", "pine_wood", "acacia_wood", "junglewood", "aspen_wood"}) do + minetest.register_craft({ + recipe = { + {"stairs:slab_"..subname}, + }, + output = "cooking:cutting_board" + }) +end +minetest.register_craft({ + recipe = { + {"default:cobble", "default:cobble", "default:cobble"}, + {"default:cobble", "stairs:slab_cobble", "default:cobble"}, + {"default:cobble", "stairs:slab_cobble", "default:cobble"} + }, + output = "cooking:oven" +}) +minetest.register_craft({ + recipe = { + {"default:cobble", "default:cobble", "default:cobble"}, + {"default:cobble", "stairs:slab_cobble", "default:cobble"}, + {"default:cobble", "default:cobble", "default:cobble"} + }, + output = "cooking:stove" +}) +minetest.register_craft({ + recipe = { + {"", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:sword_steel", "default:steel_ingot"}, + }, + output = "cooking:hand_press 2" +}) \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..81ec122 --- /dev/null +++ b/depends.txt @@ -0,0 +1,6 @@ +default +technic? +farming? +foodspoil? +flowers? +craftguide? \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..4d2f147 --- /dev/null +++ b/init.lua @@ -0,0 +1,878 @@ +cooking = {} +cooking.registered_stackcrafts = {} +cooking.registered_mixcrafts = {} +cooking.registered_cutcrafts = {} +cooking.registered_presscrafts = {} +cooking.registered_rollcrafts = {} +cooking.registered_cookcrafts = {} +cooking.registered_soupcrafts = {} + +local mp = minetest.get_modpath("cooking") + +minetest.register_craftitem("cooking:burnt_food", { + description = "Burnt Food", + inventory_image = "cooking_burnt_food.png", + on_use = minetest.item_eat(-2) +}) +minetest.register_craftitem("cooking:burnt_soup", { + description = "Burnt Soup", + inventory_image = "cooking_burnt_soup.png", + param2 = 253, + on_use = minetest.item_eat(-2, "cooking:bowl") +}) + +local function table_to_string(tbl) + local str = "" + if type(tbl) == "string" then return tbl end + for i, item in pairs(tbl) do + str = str..item + if i ~= #tbl then + str=str.."," + end + end + return str +end + +local crafttypelist = { + stack = {"Stacking", "default_tool_steelpick.png"}, + mix = {"Mixing", "default_tool_steelpick.png"}, + cut = {"Cutting", "default_tool_steelpick.png"}, + press = {"Pressing", "default_tool_steelpick.png"}, + roll = {"Rolling", "default_tool_steelpick.png"}, + stove = {"Stove", "default_tool_steelpick.png"}, + oven = {"Oven", "default_tool_steelpick.png"}, + soup = {"Soup", "default_tool_steelpick.png"}, +} +if craftguide then + for craftname, tbl in pairs(crafttypelist) do + craftguide.register_craft_type(craftname, { + description = tbl[1], + icon = tbl[2], + }) + end +end +if unified_inventory then + for craftname, tbl in pairs(crafttypelist) do + unified_inventory.register_craft_type(craftname, { + description = tbl[1], + width = 1, + height = 0, + }) + end +end +cooking.register_craft = function(tbl) + assert(tbl.type, "No Craft Type Specified") + assert(tbl.recipe, "No Craft Recipe Specified") + assert(tbl.output, "No Craft Output Specified") + if unified_inventory or craftguide then + local output = table_to_string(tbl.output) + for word in string.gmatch(tbl.output, '([^,]+)') do + output = word + break + end + local items + if type(tbl.recipe) == "string" then + items = {tbl.recipe} + else + items = table.copy(tbl.recipe) + end + if unified_inventory then + unifieditems = table.copy(items) + unified_inventory.register_craft({ + type = string.gsub(tbl.type, "^%l", string.upper), + output = output, + items = unifieditems, + }) + end + if craftguide then + craftguideitems = table.copy(items) + if (tbl.type == "stack" or tbl.type == "mix" or tbl.type == "soup") and #items ~= 1 then + local addon = "" + for i = 2, #items do + addon = addon..", " + end + for i, item in pairs(items) do + craftguideitems[#items+1-i] = item..addon + end + end + craftguide.register_craft({ + type = tbl.type, + result = output, + items = craftguideitems, + }) + end + end + if tbl.type == "oven" or tbl.type == "stove" then + tbl.recipe = table_to_string(tbl.recipe) + cooking.registered_cookcrafts[tbl.recipe] = {output = tbl.output, time = tbl.cooktime or 10, method = tbl.type} + if not cooking.registered_cookcrafts[table_to_string(tbl.output)] then + cooking.registered_cookcrafts[table_to_string(tbl.output)] = {output = tbl.burned or "cooking:burnt_food", time = 60, method = tbl.type} + end + elseif tbl.type == "cut" or tbl.type == "press" or tbl.type == "roll" then + tbl.recipe = table_to_string(tbl.recipe) + tbl.output = table_to_string(tbl.output) + cooking["registered_"..tbl.type.."crafts"][tbl.recipe] = tbl.output + elseif tbl.type == "stack" or tbl.type == "mix" or tbl.type == "soup" then + tbl.output = table_to_string(tbl.output) + cooking["registered_"..tbl.type.."crafts"][tbl.output] = tbl.recipe + else + assert(nil, "Invalid Craft Type") + end +end + +minetest.register_tool("cooking:rolling_pin", { + description = "Rolling Pin", + inventory_image = "jelys_pizzaria_rolling_pin_inv.png", + tool_capabilities = { + groupcaps = {cooking_roller = {maxlevel=3, uses=50, times={[3]=8}}} + } +}) + +local item_offsets = {} +item_offsets["cooking:hand_press"] = {input = {x=2.5/16,y=0,z=0}, output = {x=-8/16,y=-.2,z=0}} +item_offsets["cooking:pot_4"] = {x=0,y=-7/16,z=0} +item_offsets["cooking:stove"] = {fuel = {x=0,y=-.05,z=-.1}, src = {x=0,y=.425,z=-.1}} +item_offsets["cooking:stove_active"] = item_offsets["cooking:stove"] +item_offsets["cooking:oven"] = {fuel = {x=0,y=-.3,z=-.1}, src = {x=0,y=.1,z=-.1}} +item_offsets["cooking:oven_active"] = item_offsets["cooking:oven"] +item_offsets["cooking:electric_stove"] = {src = {x=0,y=.34,z=-.25}} +item_offsets["cooking:electric_stove_active"] = item_offsets["cooking:electric_stove"] +item_offsets["cooking:electric_oven"] = {src = {x=0,y=-.08,z=0}} +item_offsets["cooking:electric_oven_active"] = item_offsets["cooking:electric_oven"] + +function cooking.get_item_offset(node, index) + local offset = item_offsets[node.name] or {x=0,y=-.45,z=0} + if not offset.x then + if offset[index] then + offset = offset[index] + else + offset = offset["input"] or {x=0,y=-.45,z=0} + end + end + local yaw = minetest.facedir_to_dir(node.param2) + yaw = minetest.dir_to_yaw(yaw) + offset = vector.rotate(offset, {x=0,y=yaw,z=0}) + if type(index) == "number" then + offset.y = offset.y + (index*.06) + end + return offset +end + +local function add_item(pos, stack, param2, flatten) + local stackname = stack:get_name() + local obj = minetest.add_entity(pos, "cooking:item", stack:to_string()) + if not obj then return nil end + local itemdef = minetest.registered_items[stackname] + local yaw = minetest.facedir_to_dir(param2) + yaw = minetest.dir_to_yaw(yaw) + yaw = yaw + math.random(-20,20)/100 + if itemdef.inventory_image == "" then + obj:set_rotation({x=0, y=yaw, z=0}) + if flatten then + obj:set_properties({visual_size = {x=.33, y=.07}}) + else + local posy = math.floor(pos.y+.5) + pos.y = pos.y + .125 + if math.floor(pos.y+.5) > posy then pos.y = posy+.5 end + obj:set_pos(pos) + obj:set_properties({visual_size = {x=.25, y=.25}}) + end + else + obj:set_rotation({x=-1.57075, y=yaw, z=0}) + end + return obj +end + +local crafter_on_rightclick = function(pos, node, clicker, itemstack, pointed_thing, single) + stackname = itemstack:get_name() + if stackname == "" then return end + local meta = minetest.get_meta(pos) + local tbl = minetest.deserialize(meta:get_string("table")) or {} + if single and #tbl > 0 then return end + local stackstring = ItemStack(itemstack) + stackstring:set_count(1) + stackstring = stackstring:to_string() + table.insert(tbl, stackstring) + local pos2 = vector.add(pos, cooking.get_item_offset(node, #tbl)) + if pos2.y-pos.y > .5 then return end + meta:set_string("table", minetest.serialize(tbl)) + add_item(pos2, itemstack, node.param2, single ~= true) + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + return itemstack +end + +function cooking.remove_items(pos, consume, tbl) + local pos1 = vector.subtract(pos, .5) + local pos2 = vector.add(pos, .5) + local objects = minetest.get_objects_in_area(pos1, pos2) + for i, obj in pairs(objects) do + if obj and obj:get_entity_name() == "cooking:item" then-- and obj:get_luaentity().item == stackname then + if consume ~= true then + for i2, stackstring in pairs(tbl) do + local itemstack = ItemStack(stackstring) + local stackname = itemstack:get_name() + if obj:get_luaentity() and obj:get_luaentity().item == stackname then + --[[local drops = minetest.get_node_drops(item) + if drops then + item = drops[math.random(#drops)] + end--]] + minetest.add_item(vector.add(pos, cooking.get_item_offset(minetest.get_node(pos), "input")), itemstack) + break + end + end + end + obj:remove() + end + end +end + +local function is_stackcraft(tbl) + if not cooking.registered_stackcrafts then return end + local stacknames = {} + for i, stackstring in pairs(tbl) do + local stackname = ItemStack(stackstring):get_name() + table.insert(stacknames, stackname) + end + for name, craft in pairs(cooking.registered_stackcrafts) do + if table.concat(stacknames) == table.concat(craft) then + return name + end + end +end + +local function is_mixcraft(tbl, crafttype) + if not crafttype then crafttype = "registered_mixcrafts" end--crafttype is not really useful atm, just for a possible soup craft in future + if not string.find(crafttype, "registered_") then + crafttype = "registered_"..crafttype + end + if not cooking[crafttype] then return end + local stacknames = {} + for i, stackstring in pairs(tbl) do + local stackname = ItemStack(stackstring):get_name() + table.insert(stacknames, stackname) + end + for name, craft in pairs(cooking[crafttype]) do + local tblcopy = table.copy(stacknames) + if #stacknames == #craft then + for i, name in pairs(craft) do + local hasitem = false + for i2, name2 in pairs(tblcopy) do + if name2 == name then + table.remove(tblcopy, i2) + hasitem = true + break + end + end + if not hasitem then return end + end + end + if #tblcopy == 0 then return name end + end +end + +local function is_cutcraft(tbl) + if not cooking.registered_cutcrafts then return end + local stacknames = {} + for i, stackstring in pairs(tbl) do + local stackname = ItemStack(stackstring):get_name() + table.insert(stacknames, stackname) + end + if #tbl ~= 1 then return end + return cooking.registered_cutcrafts[stacknames[1]] +end + +local function is_presscraft(tbl) + if not cooking.registered_presscrafts then return end + local stacknames = {} + for i, stackstring in pairs(tbl) do + local stackname = ItemStack(stackstring):get_name() + table.insert(stacknames, stackname) + end + if #tbl ~= 1 then return end + return cooking.registered_presscrafts[stacknames[1]] +end + +local function is_rollcraft(tbl) + if not cooking.registered_rollcrafts then return end + local stacknames = {} + for i, stackstring in pairs(tbl) do + local stackname = ItemStack(stackstring):get_name() + table.insert(stacknames, stackname) + end + if #tbl ~= 1 then return end + return cooking.registered_rollcrafts[stacknames[1]] +end + +local function is_soupcraft(tbl) + return is_mixcraft(tbl, "registered_soupcrafts") +end + +local crafter_on_dig = function(pos, node, digger, craftfunc, successfunc, nodignode) + local meta = minetest.get_meta(pos) + local tbl = minetest.deserialize(meta:get_string("table")) + if tbl and #tbl > 0 then + local results = {} + if craftfunc then + for substring in (craftfunc(tbl) or ""):gmatch("([^,]+)") do + table.insert(results, substring) + end + end + if results and #results > 0 then + for i, result in pairs(results) do + cooking.remove_items(pos, true, tbl) + local itemstack = ItemStack(result) + if cooking_aftercraft then--if foodspoil is on, use one of its functions to get the newly crafted items expiration + local craft_grid = {} + for i2, stackstring in pairs(tbl) do + table.insert(craft_grid, ItemStack(stackstring)) + end + itemstack = cooking_aftercraft(itemstack, craft_grid) + end + tbl = {itemstack:to_string()} + if successfunc then + successfunc(pos, node, digger, itemstack) + else + minetest.add_item(vector.add(pos, cooking.get_item_offset(node, "output")), itemstack) + end + end + else + cooking.remove_items(pos, false, tbl) + end + meta:set_string("table", "") + return false + end + if not nodignode then + minetest.node_dig(pos, node, digger) + end + return true +end + +function cooking.update_furnace_objects(pos) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local tbl = {} + tbl["fuel"] = inv:get_stack("fuel", 1):to_string() + tbl["src"] = inv:get_stack("src", 1):to_string() + cooking.remove_items(pos, true, tbl) + for i, stackstring in pairs(tbl) do + local itemstack = ItemStack(stackstring) + local stackname = itemstack:get_name() + local offset = cooking.get_item_offset(node, i) + local obj = add_item(vector.add(pos, offset), itemstack, node.param2) + if obj then + local ent = obj:get_luaentity() + ent.owner = pos + ent.listname = i + --local props = obj.get_properties() + --props.pointable = true + obj:set_properties({pointable = true}) + end + end +end + +function cooking.get_craft_result(tbl) + local empty = {time = 0, item = ItemStack()}, {items = {}} + if not tbl then return empty end + local method = tbl.method + local items = table.copy(tbl.items) + if not method or not items then return empty end + local item = items[1] + if not item then return empty end + item = item:get_name() + local soup = item == "cooking:pot_4" + if soup then + local itemmeta = tbl.items[1]:get_meta() + item = ItemStack(itemmeta:get_string("soup")):get_name() + end + if not cooking.registered_cookcrafts[item] then return empty end + local craft = table.copy(cooking.registered_cookcrafts[item]) + if craft.method ~= method then return empty end + if type(craft.output) == "string" then + craft.output = ItemStack(craft.output) + end + if cooking_aftercraft then + if soup then + local itemmeta = tbl.items[1]:get_meta() + craft.output = cooking_aftercraft(ItemStack(craft.output), {ItemStack(itemmeta:get_string("soup"))}) + else + craft.output = cooking_aftercraft(ItemStack(craft.output), {tbl.items[1]}) + end + end + if soup then + local itemmeta = craft.output:get_meta() + local itemname = craft.output:get_name() + itemmeta:set_string("soup", craft.output:to_string()) + itemmeta:set_string("description", "Pot of "..craft.output:get_description()) + itemmeta:set_string("palette_index", minetest.registered_items[itemname].param2 or "0") + craft.output:set_name("cooking:pot_4") + end + local cooked = {time = craft.time, item = craft.output, replacements = craft.replacements} + local aftercooked = {items = {}} + return cooked, aftercooked +end + +dofile(mp.."/ovenstove.lua") +if technic then + dofile(mp.."/technic.lua") +end + +minetest.register_entity("cooking:item",{ + initial_properties = { + hp_max = 10, + visual="wielditem", + visual_size={x=.33,y=.33}, + collisionbox = {-.3,-.1,-.3,.3,.1,.3}, + pointable=false, + textures={"air"}, + }, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local objpos = self.object:get_pos() + local pos = self.owner or vector.round(objpos) + local meta = minetest.get_meta(pos) + local tbl = minetest.deserialize(meta:get_string("table")) + if self.listname then + local inv = meta:get_inventory() + local playerinv = puncher:get_inventory() + local itemstack = inv:get_stack(self.listname, 1) + if not playerinv or not playerinv:add_item("main", itemstack):is_empty() then + minetest.add_item(objpos, itemstack) + end + inv:remove_item(self.listname, itemstack) + cooking.update_furnace_objects(pos) + minetest.get_node_timer(pos):start(1.0) + --[[elseif tbl then --unused code, was for picking out specific items from a stack, but i decided that its better to just have you start over if you put something wrong in. + local newstack = ItemStack(tbl[#tbl]) + local inv = minetest.get_inventory({type="player", name=puncher:get_player_name()}) + if not inv or not inv:room_for_item("main", newstack) then return true end + cooking.remove_items(pos, true, tbl)--]] + --[[local index = pos.y - objpos.y + index = (.45-index)/.06 + index = math.floor(index+.5) + if not tbl[index] then return true end + minetest.chat_send_all(tostring(index))--]] + --[[table.remove(tbl) + meta:set_string("table", minetest.serialize(tbl)) + for i, stackstring in pairs(tbl) do + local itemstack = ItemStack(stackstring) + local pos2 = vector.add(pos, cooking.get_item_offset(minetest.get_node(pos), i)) + add_item(pos2, itemstack:get_name(), minetest.get_node(pos).param2, true) + end + inv:add_item("main", newstack) + return true + else + return true--]] + end + self.object:remove() + return true + end, + on_activate = function(self, staticdata) + if not staticdata or staticdata == "" then self.object:remove() return end + local itemstack = ItemStack(staticdata) + self.item = itemstack:get_name() + local itemdef = minetest.registered_items[self.item] + if not itemdef then self.object:remove() return end + self.object:set_properties({ + textures={self.item}, + wield_item = itemstack + }) + end, + get_staticdata = function(self) + --return self.item + end, +}) + +minetest.register_node("cooking:plate", { + description = "Plate", + tiles = { + "default_snow.png", + "default_snow.png", + "default_snow.png", + "default_snow.png", + "default_snow.png", + "default_snow.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.3125, -0.5, -0.3125, 0.3125, -0.4375, 0.3125}, -- NodeBox1 + {-0.4375, -0.4375, -0.5, 0.4375, -0.375, -0.3125}, -- NodeBox2 + {-0.4375, -0.4375, 0.3125, 0.4375, -0.375, 0.5}, -- NodeBox4 + {0.3125, -0.4375, -0.4375, 0.5, -0.375, 0.4375}, -- NodeBox5 + {-0.5, -0.4375, -0.4375, -0.3125, -0.375, 0.4375}, -- NodeBox6 + } + }, + --[[selection_box = { + type = "fixed", + fixed = { + {-4 / 16, -0.5, -4 / 16, 4 / 16, 0.5, 4 / 16}, + }, + },--]] + sunlight_propagates = true, + walkable = true, + groups = {oddly_breakable_by_hand = 3, cookingholder = 1}, + on_rightclick = crafter_on_rightclick, + on_dig = function(pos, node, digger) + return crafter_on_dig(pos, node, digger, is_stackcraft) + end, +}) + +minetest.register_tool("cooking:spoon", { + description = "Mixing Spoon", + inventory_image = "cooking_spoon.png", +}) + +local function register_mixer(name, value) + if not name or not value then return end + local groups = minetest.registered_items[name] + if not groups then return end + groups = groups.tool_capabilities or {} + if not groups.groupcaps then + groups.groupcaps = {} + end + groups.groupcaps.cooking_mixer = {maxlevel=3, uses=50, times={[3]=value}} + minetest.override_item(name, {tool_capabilities = groups}) +end + +register_mixer("default:stick", 12) +register_mixer("cooking:spoon", 6) + +minetest.register_node("cooking:mixing_bowl", { + description = "Mixing Bowl", + tiles = { + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.1875, -0.5, -0.1875, 0.1875, -0.4375, 0.1875}, -- NodeBox7 + {-0.3125, -0.4375, 0.1875, 0.3125, -0.375, 0.3125}, -- NodeBox8 + {-0.3125, -0.4375, -0.3125, 0.3125, -0.375, -0.1875}, -- NodeBox4 + {-0.3125, -0.375, -0.375, 0.3125, 0.0625, -0.3125}, -- NodeBox5 + {0.3125, -0.375, -0.3125, 0.375, 0.0625, 0.3125}, -- NodeBox6 + {-0.375, -0.375, -0.3125, -0.3125, 0.0625, 0.3125}, -- NodeBox7 + {-0.3125, -0.4375, -0.3125, -0.1875, -0.375, 0.3125}, -- NodeBox8 + {0.1875, -0.4375, -0.3125, 0.3125, -0.375, 0.25}, -- NodeBox10 + {-0.3125, -0.375, 0.3125, 0.3125, 0.0625, 0.375}, -- NodeBox11 + } + }, + --[[selection_box = { + type = "fixed", + fixed = { + {-4 / 16, -0.5, -4 / 16, 4 / 16, 0.5, 4 / 16}, + }, + },--]] + sunlight_propagates = true, + walkable = true, + groups = {oddly_breakable_by_hand = 3, cookingholder = 1, cooking_mixer = 3}, + on_rightclick = crafter_on_rightclick, + on_dig = function(pos, node, digger) + local craftfunc = is_mixcraft + if digger then + local tool = digger:get_wielded_item():get_tool_capabilities() + if not tool or not tool.groupcaps or not tool.groupcaps.cooking_mixer then + craftfunc = nil + end + end + return crafter_on_dig(pos, node, digger, craftfunc) + end, +}) + +local function register_cutter(name, value) + if not name or not value then return end + local groups = minetest.registered_items[name] + if not groups then return end + groups = groups.tool_capabilities or {} + if not groups.groupcaps then + groups.groupcaps = {} + end + groups.groupcaps.cooking_cutter = {maxlevel=3, uses=50, times={[3]=value}} + minetest.override_item(name, {tool_capabilities = groups}) +end + +for name, value in pairs({wood = 8, stone = 6, bronze = 4, steel = 4, mese = 4, diamond = 4}) do + register_cutter("default:sword_"..name, value) +end +--add any more swords/knives here + + +minetest.register_node("cooking:cutting_board", { + description = "Cutting Board", + tiles = { + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png", + "default_wood.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.375, -0.5, -0.3125, 0.375, -0.4375, 0.3125}, -- NodeBox1 + {0.375, -0.5, -0.125, 0.4375, -0.4375, 0.125}, -- NodeBox2 + {-0.4375, -0.5, -0.125, -0.375, -0.4375, 0.125}, -- NodeBox3 + } + }, + --[[selection_box = { + type = "fixed", + fixed = { + {-4 / 16, -0.5, -4 / 16, 4 / 16, 0.5, 4 / 16}, + }, + },--]] + sunlight_propagates = true, + walkable = true, + groups = {cookingholder = 1, cooking_cutter = 3, oddly_breakable_by_hand = 3, cooking_roller = 3}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + crafter_on_rightclick(pos, node, clicker, itemstack, pointed_thing, true) + end, + on_dig = function(pos, node, digger) + local craftfunc + if digger then + local tool = digger:get_wielded_item():get_tool_capabilities() + if tool and tool.groupcaps then + if tool.groupcaps.cooking_cutter then + craftfunc = is_cutcraft + elseif tool.groupcaps.cooking_roller then + craftfunc = is_rollcraft + end + end + end + return crafter_on_dig(pos, node, digger, craftfunc) + end, +}) + +minetest.register_node("cooking:hand_press", { + description = "Hand Press", + tiles = { + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png", + "default_steel_block.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.125, 0.375, -0.0625, 0.1875}, -- NodeBox1 + {0, -0.0625, -0.125, 0.3125, 0, 0.1875}, -- NodeBox2 + {-0.0625, -0.0625, -0.125, 0, 0.125, 0.1875}, -- NodeBox4 + {0.3125, -0.0625, -0.125, 0.375, 0.125, 0.1875}, -- NodeBox5 + {0, -0.0625, -0.1875, 0.3125, 0.125, -0.125}, -- NodeBox6 + {0, -0.0625, 0.1875, 0.3125, 0.125, 0.25}, -- NodeBox8 + --{-0.4375, -0.25, -0.0625, -0.25, -0.0625, 0.125}, -- NodeBox9 + {0.375, -0.25, -0.0625, 0.4375, 0.25, 0.0625}, -- NodeBox10 + } + }, + --[[selection_box = { + type = "fixed", + fixed = { + {-4 / 16, -0.5, -4 / 16, 4 / 16, 0.5, 4 / 16}, + }, + },--]] + sunlight_propagates = true, + walkable = true, + groups = {cookingholder = 1, oddly_breakable_by_hand = 3}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + crafter_on_rightclick(pos, node, clicker, itemstack, pointed_thing, true) + end, + on_dig = function(pos, node, digger) + return crafter_on_dig(pos, node, digger, is_presscraft) + end, +}) + +--Soup Pot + +local function on_soup_craft(pos, node, digger, itemstack) + local itemname = itemstack:get_name() + local recipedef = cooking.registered_soupcrafts[itemname] + node.param2 = minetest.registered_items[itemname].param2 or node.param2 + minetest.swap_node(pos, node) + local meta = minetest.get_meta(pos) + meta:set_string("soup", itemstack:to_string()) + meta:set_string("description", "Pot of "..itemstack:get_description()) +end + +local function pot_on_punch(pos, node, player, replacement) + local meta = minetest.get_meta(pos) + local player_inv = player:get_inventory() + local itemstack = player:get_wielded_item() + if itemstack:get_name() == "cooking:bowl" and meta:get_string("soup") ~= "" then + node.name = replacement + minetest.swap_node(pos, node) + itemstack:take_item(1) + if itemstack:get_count() > 0 then + minetest.add_item(pos, player_inv:add_item("main", meta:get_string("soup"))) + else + itemstack:replace(meta:get_string("soup")) + end + player:set_wielded_item(itemstack) + if replacement == "cooking:pot_0" then + node.name = "cooking:pot_0" + node.param2 = 0 + minetest.set_node(pos, node) + end + elseif itemstack:get_name() == "bucket:bucket_empty" then + node.name = "cooking:pot_0" + node.param2 = 0 + if meta:get_string("soup") == "" then + itemstack:replace("bucket:bucket_water") + player:set_wielded_item(itemstack) + end + crafter_on_dig(pos, node, player, nil, nil, true) + minetest.set_node(pos, node) + end + return itemstack +end +local potdef = { + drawtype = "mesh", + mesh = "cooking_pot_4.b3d", + use_texture_alpha = true, + tiles = {{name = "cooking_potuv.png", color = "white"}}, + overlay_tiles = {{name = "cooking_pot_overlay.png"}}, + description= "Filled Pot", + paramtype = "light", + paramtype2 = "color", + palette = "palette.png", + groups = {oddly_breakable_by_hand=3, cookingholder = 1, cooking_mixer = 3, not_in_creative_inventory = 1}, + legacy_facedir_simple = true, + selection_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.375, 0.25, 0.1875, -0.25}, -- NodeBox1 + {-0.25, -0.5, 0.25, 0.25, 0.1875, 0.375}, -- NodeBox3 + {-0.375, -0.5, -0.25, -0.25, 0.1875, 0.25}, -- NodeBox4 + {0.25, -0.5, -0.25, 0.375, 0.1875, 0.25}, -- NodeBox5 + {-0.25, -0.5, -0.25, 0.25, -0.375, 0.25}, -- NodeBox6 + } + }, + on_punch = function(pos, node, player) + return pot_on_punch(pos, node, player, "cooking:pot_3") + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + if meta:get_string("soup") == "" then + return crafter_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + else + return itemstack + end + end, + on_dig = function(pos, node, digger) + local craftfunc = is_soupcraft + if digger then + local tool = digger:get_wielded_item():get_tool_capabilities() + if not tool or not tool.groupcaps or not tool.groupcaps.cooking_mixer then + craftfunc = nil + end + end + return crafter_on_dig(pos, node, digger, craftfunc, on_soup_craft) + end, + preserve_metadata = function(pos, oldnode, oldmeta, drops) + for i, drop in pairs(drops) do + local itemmeta = drop:get_meta() + itemmeta:set_string("soup", oldmeta.soup) + itemmeta:set_string("description", oldmeta.description) + end + return drops + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + local itemmeta = itemstack:get_meta() + local meta = minetest.get_meta(pos) + meta:set_string("description", itemmeta:get_string("description")) + meta:set_string("soup", itemmeta:get_string("soup")) + end, +} +minetest.register_node("cooking:pot_4", table.copy(potdef)) + +potdef.description= "3/4 Filled Pot" +potdef.on_dig = nil +potdef.on_rightclick = nil +potdef.mesh = "cooking_pot_3.b3d" +potdef.groups = {oddly_breakable_by_hand=3, not_in_creative_inventory=1} +potdef.on_punch = function(pos, node, player) + return pot_on_punch(pos, node, player, "cooking:pot_2") +end +minetest.register_node("cooking:pot_3", table.copy(potdef)) + +potdef.description= "1/2 Filled Pot" +potdef.mesh = "cooking_pot_2.b3d" +potdef.on_punch = function(pos, node, player) + return pot_on_punch(pos, node, player, "cooking:pot_1") +end +minetest.register_node("cooking:pot_2", table.copy(potdef)) + +potdef.description= "1/4 Filled Pot" +potdef.mesh = "cooking_pot_1.b3d" +potdef.on_punch = function(pos, node, player) + return pot_on_punch(pos, node, player, "cooking:pot_0") +end +minetest.register_node("cooking:pot_1", table.copy(potdef)) + + +potdef.description= "Empty Pot" +potdef.mesh = "cooking_pot_0.b3d" +potdef.groups = {oddly_breakable_by_hand=3} +potdef.on_punch = nil +potdef.on_rightclick = function(pos, node, clicker, itemstack) + if itemstack:get_name() == "bucket:bucket_water" then + node.name = "cooking:pot_4" + minetest.swap_node(pos, node) + return {name="bucket:bucket_empty"} + end +end +potdef.preserve_metadata = function(pos, oldnode, oldmeta, drops) + for i, drop in pairs(drops) do + local itemmeta = drop:get_meta() + itemmeta:from_table({}) + end + return drops +end +potdef.after_place_node = nil +minetest.register_node("cooking:pot_0", table.copy(potdef)) + +minetest.register_craftitem("cooking:bowl", { + description = "Bowl", + inventory_image = "cooking_bowl.png", + param2 = 222 +}) + +minetest.register_lbm({ + name = "cooking:additems", + nodenames = {"group:cookingholder"}, + run_at_every_load = true, + action = function(pos, node, _, _) + if minetest.get_item_group(node.name, "furnace") > 0 then + return cooking.update_furnace_objects(pos) + end + local meta = minetest.get_meta(pos) + local tbl = minetest.deserialize(meta:get_string("table")) + if not tbl then return end + for i, stackstring in pairs(tbl) do + local itemstack = ItemStack(stackstring) + local pos2 = vector.add(pos, cooking.get_item_offset(node, i)) + add_item(pos2, itemstack, node.param2, true) + end + end, +}) + +dofile(mp.."/crafts.lua") \ No newline at end of file diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..db998f6 --- /dev/null +++ b/license.txt @@ -0,0 +1,36 @@ +in ovenstove.lua there is some copied and edited code from minetest_game, which is under the following license: +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2018 celeron55, Perttu Ahola +Copyright (C) 2011-2018 Various Minetest developers and contributors + +This program is free software; you can redistribute it and/or modify it under the terms +of the GNU Lesser General Public License as published by the Free Software Foundation; +either version 2.1 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + +on technic.lua there is some copied and edited code from the technic mod, which is under the following license: +------------------------- +LGPLv2 + +Credits for technic mod: +kpoppel +Nekogloop +Nore/Ekdohibs +ShadowNinja +VanessaE +And many others... + +jelys_pizzaria_rolling_pin_inv.png +------------------------------ +Attribution-ShareAlike 3.0 (CC BY-SA 3.0) Extex +inspired by https://www.brik.co/blogs/pixel-art/rolling-pin-pixel-art + +all other code, textures, and models: +---------------------- +Attribution 2.0 Generic (CC BY 2.0) Elkien3 \ No newline at end of file diff --git a/models/cooking_pot_0.b3d b/models/cooking_pot_0.b3d new file mode 100644 index 0000000..c949afa Binary files /dev/null and b/models/cooking_pot_0.b3d differ diff --git a/models/cooking_pot_1.b3d b/models/cooking_pot_1.b3d new file mode 100644 index 0000000..6e6747a Binary files /dev/null and b/models/cooking_pot_1.b3d differ diff --git a/models/cooking_pot_2.b3d b/models/cooking_pot_2.b3d new file mode 100644 index 0000000..b309601 Binary files /dev/null and b/models/cooking_pot_2.b3d differ diff --git a/models/cooking_pot_3.b3d b/models/cooking_pot_3.b3d new file mode 100644 index 0000000..4410eec Binary files /dev/null and b/models/cooking_pot_3.b3d differ diff --git a/models/cooking_pot_4.b3d b/models/cooking_pot_4.b3d new file mode 100644 index 0000000..0f066cb Binary files /dev/null and b/models/cooking_pot_4.b3d differ diff --git a/models/electric_oven.b3d b/models/electric_oven.b3d new file mode 100644 index 0000000..903f3ac Binary files /dev/null and b/models/electric_oven.b3d differ diff --git a/models/electric_stove.b3d b/models/electric_stove.b3d new file mode 100644 index 0000000..d3b26f0 Binary files /dev/null and b/models/electric_stove.b3d differ diff --git a/models/wood_oven.b3d b/models/wood_oven.b3d new file mode 100644 index 0000000..a9a3cf6 Binary files /dev/null and b/models/wood_oven.b3d differ diff --git a/models/wood_stove.b3d b/models/wood_stove.b3d new file mode 100644 index 0000000..7ef7656 Binary files /dev/null and b/models/wood_stove.b3d differ diff --git a/ovenstove.lua b/ovenstove.lua new file mode 100644 index 0000000..99e5282 --- /dev/null +++ b/ovenstove.lua @@ -0,0 +1,451 @@ +--some code is copied and edited from default/furnace.lua from minetest_game +--GNU Lesser General Public License, version 2.1 +--Copyright (C) 2011-2018 celeron55, Perttu Ahola +--Copyright (C) 2011-2018 Various Minetest developers and contributors +--see license.txt for more info + +-- support for MT game translation. +local S = default.get_translator +--[[ +function cooking.get_furnace_active_formspec(fuel_percent, item_percent) + return "size[8,8.5]".. + "list[context;src;3.75,0.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. + (fuel_percent)..":default_furnace_fire_fg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:".. + (item_percent)..":gui_furnace_arrow_fg.png^[transformR0]".. + --"list[context;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + --"listring[context;dst]".. + "listring[current_player;main]".. + "listring[context;src]".. + "listring[current_player;main]".. + "listring[context;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +function cooking.get_furnace_inactive_formspec() + return "size[8,8.5]".. + "list[context;src;3.75,0.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR0]".. + --"list[context;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + --"listring[context;dst]".. + "listring[current_player;main]".. + "listring[context;src]".. + "listring[current_player;main]".. + "listring[context;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end--]] + +-- +-- Node callback functions that are the same for active and inactive furnace +-- + +local function can_dig(pos, player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + if inv:is_empty("src") then + meta:set_string("infotext", S((method:gsub("^%l", string.upper)).." is empty")) + end + return stack:get_count() + else + return 0 + end + elseif listname == "src" then + if inv:is_empty("src") then--or not inv:contains_item(listname, stack) then + return 1--stack:get_count() + else + return 0 + end + elseif listname == "dst" then + return 0 + end +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function swap_node(pos, name) + local node = minetest.get_node(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) +end + +local function furnace_node_timer(pos, elapsed) + local method = string.gsub(minetest.get_node(pos).name, "cooking:", "") + method = string.gsub(method, "_active", "") + -- + -- Initialize metadata + -- + local meta = minetest.get_meta(pos) + local fuel_time = meta:get_float("fuel_time") or 0 + local src_time = meta:get_float("src_time") or 0 + local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 + + local inv = meta:get_inventory() + local srclist, fuellist + local dst_full = false + + local cookable, cooked + local fuel + + local update = true + while elapsed > 0 and update do + update = false + + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") + + -- + -- Cooking + -- + + -- Check if we have cookable content + local aftercooked + cooked, aftercooked = cooking.get_craft_result({method = method, width = 1, items = srclist}) + cookable = cooked.time ~= 0 + --local firepos = minetest.find_node_near(pos, 2, "air") + --minetest.set_node(firepos, {name = "fire:basic_flame"}) + local el = math.min(elapsed, fuel_totaltime - fuel_time) + if cookable then -- fuel lasts long enough, adjust el to cooking duration + el = math.min(el, cooked.time - src_time) + end + + -- Check if we have enough fuel to burn + if fuel_time < fuel_totaltime then + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + el + -- If there is a cookable item then check if it is ready yet + if cookable then + src_time = src_time + el + if src_time >= cooked.time then + -- Place result in dst list if possible + --if inv:room_for_item("dst", aftercooked.items[1]) then + --inv:add_item("dst", aftercooked.items[1]) + local item = cooked.item + inv:set_stack("src", 1, item) + cooking.update_furnace_objects(pos) + src_time = src_time - cooked.time + update = true + --else + -- dst_full = true + --end + else + -- Item could not be cooked: probably missing fuel + update = true + end + end + else + -- Furnace ran out of fuel + if cookable then + -- We need to get new fuel + local afterfuel + fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel.time = fuel.time*6 + + if fuel.time == 0 then + -- No valid fuel in fuel list + fuel_totaltime = 0 + src_time = 0 + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + -- Put replacements in dst list or drop them on the furnace. + local replacements = fuel.replacements + if replacements[1] then + --local leftover = inv:add_item("dst", replacements[1]) + --if not leftover:is_empty() then + local above = vector.new(pos.x, pos.y + 1, pos.z) + local drop_pos = minetest.find_node_near(above, 1, {"air"}) or above + minetest.item_drop(replacements[1], nil, drop_pos) + --end + end + update = true + cooking.update_furnace_objects(pos) + fuel_totaltime = fuel.time + (fuel_totaltime - fuel_time) + end + else + -- We don't need to get new fuel since there is no cookable item + fuel_totaltime = 0 + src_time = 0 + end + fuel_time = 0 + end + + elapsed = elapsed - el + end + + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist and srclist[1]:is_empty() then + src_time = 0 + end + + -- + -- Update formspec, infotext and node + -- + local formspec + local item_state + local item_percent = 0 + if cookable then + item_percent = math.floor(src_time / cooked.time * 100) + if dst_full then + item_state = S("100% (output full)") + else + item_state = S("@1%", item_percent) + end + else + if srclist and not srclist[1]:is_empty() then + item_state = S("Not cookable") + else + item_state = S("Empty") + end + end + + local fuel_state = S("Empty") + local active = false + local result = false + + if fuel_totaltime ~= 0 then + active = true + local fuel_percent = 100 - math.floor(fuel_time / fuel_totaltime * 100) + fuel_state = S("@1%", fuel_percent) + --formspec = cooking.get_furnace_active_formspec(fuel_percent, item_percent) + swap_node(pos, "cooking:"..method.."_active") + -- make sure timer restarts automatically + result = true + else + if fuellist and not fuellist[1]:is_empty() then + fuel_state = S("@1%", 0) + end + --formspec = cooking.get_furnace_inactive_formspec() + swap_node(pos, "cooking:"..method) + -- stop timer on the inactive furnace + minetest.get_node_timer(pos):stop() + end + + + local infotext + if active then + infotext = S((method:gsub("^%l", string.upper)).." active") + else + infotext = S((method:gsub("^%l", string.upper)).." inactive") + end + infotext = infotext .. "\n" .. S("(Item: @1; Fuel: @2)", item_state, fuel_state) + + -- + -- Set meta values + -- + meta:set_float("fuel_totaltime", fuel_totaltime) + meta:set_float("fuel_time", fuel_time) + meta:set_float("src_time", src_time) + --meta:set_string("formspec", formspec) + meta:set_string("infotext", infotext) + + return result +end + +-- +-- Node definitions +-- + +local furnace_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + minetest.get_node_timer(pos):start(1.0) + local inv = meta:get_inventory() + if minetest.get_craft_result({method="fuel", width=1, items={itemstack}}).time ~= 0 and inv:room_for_item("fuel", itemstack) then + itemstack = inv:add_item("fuel", itemstack) + cooking.update_furnace_objects(pos) + elseif inv:is_empty("src") then + local tempstack = ItemStack(itemstack) + tempstack:set_count(1) + inv:add_item("src", tempstack) + itemstack:take_item(1) + cooking.update_furnace_objects(pos) + end + return itemstack +end + +local ovenstovedef = { + drawtype = "mesh", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky=2, cookingholder = 1, furnace = 1}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + + --can_dig = can_dig, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('src', 1) + inv:set_size('fuel', 1) + --inv:set_size('dst', 1) + furnace_node_timer(pos, 0) + end, + + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local tbl = {} + tbl["fuel"] = inv:get_stack("fuel", 1):to_string() + tbl["src"] = inv:get_stack("src", 1):to_string() + cooking.remove_items(pos, false, tbl) + end, + + on_rightclick = furnace_rightclick, + + on_metadata_inventory_move = function(pos) + minetest.get_node_timer(pos):start(1.0) + end, + on_metadata_inventory_put = function(pos) + -- start timer function, it will sort out whether furnace can burn or not. + minetest.get_node_timer(pos):start(1.0) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "src", drops) + default.get_inventory_drops(pos, "fuel", drops) + --default.get_inventory_drops(pos, "dst", drops) + drops[#drops+1] = "cooking:stove" + minetest.remove_node(pos) + return drops + end, + + on_timer = furnace_node_timer, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +} + +--OVEN +ovenstovedef.description = S("Oven") +ovenstovedef.mesh = "wood_oven.b3d" +ovenstovedef.tiles = {"wood_oven_uv.png"} +ovenstovedef.selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, -0.375, 0.5, 0.5}, -- NodeBox3 + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, -- NodeBox4 + {0.375, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox5 + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, -- NodeBox6 + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, -- NodeBox7 + {-0.375, -0.0625, -0.5, 0.375, 0.0625, 0.375}, -- NodeBox6 + } +} + +minetest.register_node("cooking:oven", table.copy(ovenstovedef)) + + +--STOVE +ovenstovedef.description = S("Stove") +ovenstovedef.mesh = "wood_stove.b3d" +ovenstovedef.tiles = {"wood_stove_uv.png"} +ovenstovedef.selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, -0.3125, 0.375, 0.5}, -- NodeBox3 + {-0.5, -0.5, 0.375, 0.5, 0.375, 0.5}, -- NodeBox4 + {0.3125, -0.5, -0.5, 0.5, 0.375, 0.5}, -- NodeBox5 + {-0.5, 0.1875, -0.5, 0.5, 0.375, 0.5}, -- NodeBox6 + {-0.5, -0.5, -0.5, 0.5, -0.125, 0.5}, -- NodeBox7 + } +} + +minetest.register_node("cooking:stove", table.copy(ovenstovedef)) + +ovenstovedef = { + drawtype = "mesh", + paramtype = "light", + + on_rightclick = furnace_rightclick, + + paramtype2 = "facedir", + light_source = 8, + groups = {cracky=2, not_in_creative_inventory=1, cookingholder = 1, furnace = 1}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + + --can_dig = can_dig, + on_timer = furnace_node_timer, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +} + +--ACTIVE OVEN +ovenstovedef.description = S("Oven") +ovenstovedef.mesh = "wood_oven.b3d" +ovenstovedef.tiles = {"wood_oven_uv.png^fireboi.png"} +ovenstovedef.use_texture_alpha = true +ovenstovedef.selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, -0.375, 0.5, 0.5}, -- NodeBox3 + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, -- NodeBox4 + {0.375, -0.5, -0.5, 0.5, 0.5, 0.5}, -- NodeBox5 + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, -- NodeBox6 + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, -- NodeBox7 + {-0.375, -0.0625, -0.5, 0.375, 0.0625, 0.375}, -- NodeBox6 + } +} + +ovenstovedef.drop = "cooking:oven" +minetest.register_node("cooking:oven_active", table.copy(ovenstovedef)) + +--ACTIVE STOVE +ovenstovedef.description = S("Stove") +ovenstovedef.mesh = "wood_stove.b3d" +ovenstovedef.tiles = {"wood_stove_uv.png^fireboi.png"} +ovenstovedef.selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, -0.3125, 0.375, 0.5}, -- NodeBox3 + {-0.5, -0.5, 0.375, 0.5, 0.375, 0.5}, -- NodeBox4 + {0.3125, -0.5, -0.5, 0.5, 0.375, 0.5}, -- NodeBox5 + {-0.5, 0.1875, -0.5, 0.5, 0.375, 0.5}, -- NodeBox6 + {-0.5, -0.5, -0.5, 0.5, -0.125, 0.5}, -- NodeBox7 + } +} + +ovenstovedef.drop = "cooking:stove" +minetest.register_node("cooking:stove_active", table.copy(ovenstovedef)) \ No newline at end of file diff --git a/technic.lua b/technic.lua new file mode 100644 index 0000000..30d519e --- /dev/null +++ b/technic.lua @@ -0,0 +1,236 @@ +local S = technic.getter + +local fs_helpers = pipeworks.fs_helpers +local tube_entry = "^pipeworks_tube_connection_metallic.png" + +local connect_default = {"bottom", "back", "left", "right"} + +local function round(v) + return math.floor(v + 0.5) +end + +local furnace_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + minetest.get_node_timer(pos):start(1.0) + local inv = meta:get_inventory() + if not inv:is_empty("src") then return itemstack end + local tempstack = ItemStack(itemstack) + tempstack:set_count(1) + inv:add_item("src", tempstack) + itemstack:take_item(1) + cooking.update_furnace_objects(pos) + return itemstack +end + +function register_base_machine(data) + local typename = data.typename + local machine_name = data.machine_name + local machine_desc = data.machine_desc + local tier = data.tier + local ltier = string.lower(tier) + + data.modname = data.modname or minetest.get_current_modname() + + local groups = {cracky = 2, technic_machine = 1, ["technic_"..ltier] = 1, cookingholder = 1, furnace = 1} + + local active_groups = {not_in_creative_inventory = 1} + for k, v in pairs(groups) do active_groups[k] = v end + + local on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local tbl = {} + tbl["fuel"] = inv:get_stack("fuel", 1):to_string() + tbl["src"] = inv:get_stack("src", 1):to_string() + cooking.remove_items(pos, false, tbl) + end + + local run = function(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local eu_input = meta:get_int(tier.."_EU_input") + + local machine_desc_tier = machine_desc:format(tier) + local machine_node = data.modname..":"..machine_name + local machine_demand = data.demand + + -- Setup meta data if it does not exist. + if not eu_input then + meta:set_int(tier.."_EU_demand", machine_demand[1]) + meta:set_int(tier.."_EU_input", 0) + return + end + + local EU_upgrade, tube_upgrade = 0, 0 + + local powered = eu_input >= machine_demand[EU_upgrade+1] + if powered then + meta:set_int("src_time", meta:get_int("src_time") + round(data.speed*10)) + end + --while true do + local result = cooking.get_craft_result({method = typename, width = 1, items = inv:get_list("src")}) + if not result or result.time == 0 then + technic.swap_node(pos, machine_node) + meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier)) + meta:set_int(tier.."_EU_demand", 0) + meta:set_int("src_time", 0) + return + end + meta:set_int(tier.."_EU_demand", machine_demand[EU_upgrade+1]) + technic.swap_node(pos, machine_node.."_active") + meta:set_string("infotext", S("%s Active"):format(machine_desc_tier)) + if meta:get_int("src_time") < round(result.time*10) then + if not powered then + technic.swap_node(pos, machine_node) + meta:set_string("infotext", S("%s Unpowered"):format(machine_desc_tier)) + end + return + end + --[[local output = result.output + if type(output) ~= "table" then output = { output } end + local output_stacks = {} + for _, o in ipairs(output) do + table.insert(output_stacks, ItemStack(o)) + end + local room_for_output = true + inv:set_size("dst_tmp", inv:get_size("dst")) + for _, o in ipairs(output_stacks) do + if not inv:room_for_item("dst_tmp", o) then + room_for_output = false + break + end + inv:add_item("dst_tmp", o) + end--]] + --[[if not room_for_output then + technic.swap_node(pos, machine_node) + meta:set_string("infotext", S("%s Idle"):format(machine_desc_tier)) + meta:set_int(tier.."_EU_demand", 0) + meta:set_int("src_time", round(result.time*10)) + return + end--]] + meta:set_int("src_time", meta:get_int("src_time") - round(result.time*10)) + inv:set_stack("src", 1, result.item) + cooking.update_furnace_objects(pos) + --inv:set_list("src", result.new_input) + --inv:set_list("dst", inv:get_list("dst_tmp")) + --end + end + + local tentry = tube_entry + if ltier == "lv" then + tentry = "" + end + + minetest.register_node(data.modname..":"..machine_name, { + description = machine_desc:format(tier), + tiles = {"electric_"..typename.."_uv.png"}, + drawtype = "mesh", + mesh = "electric_"..typename..".b3d", + paramtype = "light", + paramtype2 = "facedir", + groups = groups, + tube = data.tube and tube or nil, + selection_box = data.selection_box, + connect_sides = data.connect_sides or connect_default, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + + local form_buttons = "" + + meta:set_string("infotext", machine_desc:format(tier)) + meta:set_int("tube_time", 0) + --meta:set_string("formspec", formspec..form_buttons) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("dst", 1) + end, + on_destruct = on_destruct, + on_rightclick = furnace_rightclick, + --can_dig = technic.machine_can_dig, + allow_metadata_inventory_put = technic.machine_inventory_put, + allow_metadata_inventory_take = technic.machine_inventory_take, + allow_metadata_inventory_move = technic.machine_inventory_move, + technic_run = run, + after_place_node = data.tube and pipeworks.after_place, + after_dig_node = technic.machine_after_dig_node, + }) + + minetest.register_node(data.modname..":"..machine_name.."_active",{ + description = machine_desc:format(tier), + tiles = {"electric_"..typename.."_uv.png"}, + drawtype = "mesh", + mesh = "electric_"..typename..".b3d", + paramtype = "light", + paramtype2 = "facedir", + drop = data.modname..":"..machine_name, + groups = active_groups, + selection_box = data.selection_box, + connect_sides = data.connect_sides or connect_default, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + allow_metadata_inventory_put = technic.machine_inventory_put, + allow_metadata_inventory_take = technic.machine_inventory_take, + allow_metadata_inventory_move = technic.machine_inventory_move, + technic_run = run, + technic_disabled_machine_name = data.modname..":"..machine_name, + on_rightclick = furnace_rightclick, + on_destruct = on_destruct + }) + + technic.register_machine(tier, data.modname..":"..machine_name, technic.receiver) + technic.register_machine(tier, data.modname..":"..machine_name.."_active", technic.receiver) + +end -- End registration + +register_base_machine({ + typename = "oven", + machine_name = "electric_oven", + machine_desc = "Electric Oven", + tier="LV", + demand={50}, + speed = 1, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.375, -0.3125, 0.5, 0.5}, -- NodeBox3 + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, -- NodeBox4 + {0.3125, -0.5, -0.375, 0.5, 0.5, 0.5}, -- NodeBox5 + {-0.5, 0.1875, -0.375, 0.5, 0.5, 0.5}, -- NodeBox6 + {-0.5, -0.5, -0.375, 0.5, -0.125, 0.5}, -- NodeBox7 + } + } +}) +register_base_machine({ + typename = "stove", + machine_name = "electric_stove", + machine_desc = "Electric Stove", + tier="LV", + demand={50}, + speed = 1, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.3125, 0.5}, -- NodeBox6 + } + } +}) + +minetest.register_craft({ + recipe = { + {"default:steel_ingot", "basic_materials:heating_element", "default:steel_ingot"}, + {"default:steel_ingot", "technic:lv_cable", "default:steel_ingot"}, + {"default:steel_ingot", "technic:lv_cable", "default:steel_ingot"} + }, + output = "cooking:electric_stove" +}) +minetest.register_craft({ + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "basic_materials:heating_element", "default:steel_ingot"}, + {"default:steel_ingot", "technic:lv_cable", "default:steel_ingot"} + }, + output = "cooking:electric_oven" +}) diff --git a/textures/cooking_apple_pie.png b/textures/cooking_apple_pie.png new file mode 100644 index 0000000..2def3e9 Binary files /dev/null and b/textures/cooking_apple_pie.png differ diff --git a/textures/cooking_apple_pie_uncooked.png b/textures/cooking_apple_pie_uncooked.png new file mode 100644 index 0000000..86d7cf6 Binary files /dev/null and b/textures/cooking_apple_pie_uncooked.png differ diff --git a/textures/cooking_blueberry_jam.png b/textures/cooking_blueberry_jam.png new file mode 100644 index 0000000..3448cf4 Binary files /dev/null and b/textures/cooking_blueberry_jam.png differ diff --git a/textures/cooking_bowl.png b/textures/cooking_bowl.png new file mode 100644 index 0000000..44a3f5a Binary files /dev/null and b/textures/cooking_bowl.png differ diff --git a/textures/cooking_bread_sliced.png b/textures/cooking_bread_sliced.png new file mode 100644 index 0000000..4fed626 Binary files /dev/null and b/textures/cooking_bread_sliced.png differ diff --git a/textures/cooking_bread_with_jam.png b/textures/cooking_bread_with_jam.png new file mode 100644 index 0000000..4d632b4 Binary files /dev/null and b/textures/cooking_bread_with_jam.png differ diff --git a/textures/cooking_bun.png b/textures/cooking_bun.png new file mode 100644 index 0000000..34bb3bf Binary files /dev/null and b/textures/cooking_bun.png differ diff --git a/textures/cooking_bun_uncooked.png b/textures/cooking_bun_uncooked.png new file mode 100644 index 0000000..4e6ee0d Binary files /dev/null and b/textures/cooking_bun_uncooked.png differ diff --git a/textures/cooking_burnt_food.png b/textures/cooking_burnt_food.png new file mode 100644 index 0000000..a639750 Binary files /dev/null and b/textures/cooking_burnt_food.png differ diff --git a/textures/cooking_burnt_soup.png b/textures/cooking_burnt_soup.png new file mode 100644 index 0000000..9a42fbd Binary files /dev/null and b/textures/cooking_burnt_soup.png differ diff --git a/textures/cooking_chopped_apple.png b/textures/cooking_chopped_apple.png new file mode 100644 index 0000000..f043901 Binary files /dev/null and b/textures/cooking_chopped_apple.png differ diff --git a/textures/cooking_mushroom_soup.png b/textures/cooking_mushroom_soup.png new file mode 100644 index 0000000..bad2101 Binary files /dev/null and b/textures/cooking_mushroom_soup.png differ diff --git a/textures/cooking_mushroom_soup_uncooked.png b/textures/cooking_mushroom_soup_uncooked.png new file mode 100644 index 0000000..fa0bec8 Binary files /dev/null and b/textures/cooking_mushroom_soup_uncooked.png differ diff --git a/textures/cooking_pie_crust.png b/textures/cooking_pie_crust.png new file mode 100644 index 0000000..df4e67e Binary files /dev/null and b/textures/cooking_pie_crust.png differ diff --git a/textures/cooking_pot_overlay.png b/textures/cooking_pot_overlay.png new file mode 100644 index 0000000..d31fb47 Binary files /dev/null and b/textures/cooking_pot_overlay.png differ diff --git a/textures/cooking_pot_overlay_opaque.png b/textures/cooking_pot_overlay_opaque.png new file mode 100644 index 0000000..654d65f Binary files /dev/null and b/textures/cooking_pot_overlay_opaque.png differ diff --git a/textures/cooking_potuv.png b/textures/cooking_potuv.png new file mode 100644 index 0000000..736e413 Binary files /dev/null and b/textures/cooking_potuv.png differ diff --git a/textures/cooking_spoon.png b/textures/cooking_spoon.png new file mode 100644 index 0000000..557a34b Binary files /dev/null and b/textures/cooking_spoon.png differ diff --git a/textures/cooking_sugar.png b/textures/cooking_sugar.png new file mode 100644 index 0000000..6254ebd Binary files /dev/null and b/textures/cooking_sugar.png differ diff --git a/textures/cooking_toast.png b/textures/cooking_toast.png new file mode 100644 index 0000000..f6f147d Binary files /dev/null and b/textures/cooking_toast.png differ diff --git a/textures/cooking_toast_with_jam.png b/textures/cooking_toast_with_jam.png new file mode 100644 index 0000000..576da21 Binary files /dev/null and b/textures/cooking_toast_with_jam.png differ diff --git a/textures/electric_oven_uv.png b/textures/electric_oven_uv.png new file mode 100644 index 0000000..0156082 Binary files /dev/null and b/textures/electric_oven_uv.png differ diff --git a/textures/electric_stove_uv.png b/textures/electric_stove_uv.png new file mode 100644 index 0000000..9a5dc48 Binary files /dev/null and b/textures/electric_stove_uv.png differ diff --git a/textures/fireboi.png b/textures/fireboi.png new file mode 100644 index 0000000..03e0385 Binary files /dev/null and b/textures/fireboi.png differ diff --git a/textures/invis.png b/textures/invis.png new file mode 100644 index 0000000..7a96934 Binary files /dev/null and b/textures/invis.png differ diff --git a/textures/jelys_pizzaria_rolling_pin_inv.png b/textures/jelys_pizzaria_rolling_pin_inv.png new file mode 100644 index 0000000..c754835 Binary files /dev/null and b/textures/jelys_pizzaria_rolling_pin_inv.png differ diff --git a/textures/palette.png b/textures/palette.png new file mode 100644 index 0000000..fb39b3c Binary files /dev/null and b/textures/palette.png differ diff --git a/textures/wood_oven_uv.png b/textures/wood_oven_uv.png new file mode 100644 index 0000000..539b254 Binary files /dev/null and b/textures/wood_oven_uv.png differ diff --git a/textures/wood_stove_uv.png b/textures/wood_stove_uv.png new file mode 100644 index 0000000..4cc0aa9 Binary files /dev/null and b/textures/wood_stove_uv.png differ