diff --git a/mods/inventory_plus/depends.txt b/mods/inventory_plus/depends.txt new file mode 100644 index 0000000..2224f16 --- /dev/null +++ b/mods/inventory_plus/depends.txt @@ -0,0 +1,2 @@ +default? +creative? diff --git a/mods/inventory_plus/init.lua b/mods/inventory_plus/init.lua new file mode 100644 index 0000000..c827f07 --- /dev/null +++ b/mods/inventory_plus/init.lua @@ -0,0 +1,139 @@ +--[[ + +Inventory Plus+ for Minetest + +Copyright (c) 2012 cornernote, Brett O'Donnell +Copyright (c) 2013 Zeg9 +Source Code: https://github.com/Zeg9/minetest-inventory_plus +License: GPLv3 + +]]-- + +--[[ +TODO: + * Include a few button textures, especially for "abandoned" mods + -> Done: bags + -> Todo: home GUI, mobf settings (if it still exists),... + * Limit the number of buttons displayed, and then: + * Multiple button pages (inventory can only display 9 buttons, and creative 6) + * Fallback to text if no image is present ? +]]-- + + +-- expose api +inventory_plus = {} + +-- tell that we are inventory++, not inventory_plus +-- ...so mods know if they can use our functions like remove_button +inventory_plus.plusplus = true + +-- define buttons +inventory_plus.buttons = {} + +-- default inventory page +inventory_plus.default = minetest.setting_get("inventory_default") or "main" + +-- original inventory formspec, per player +inventory_plus.inventory = {} + +-- register_button +inventory_plus.register_button = function(player,name,...) + local player_name = player:get_player_name() + if inventory_plus.buttons[player_name] == nil then + inventory_plus.buttons[player_name] = {} + end + for _, i in ipairs(inventory_plus.buttons[player_name]) do + if i == name then return end -- only register buttons once + end + table.insert(inventory_plus.buttons[player_name], name) +end + +inventory_plus.remove_button = function(player,name) + local player_name = player:get_player_name() + if inventory_plus.buttons[player_name] == nil then + inventory_plus.buttons[player_name] = {} + end + local index = nil + for i, n in ipairs(inventory_plus.buttons[player_name]) do + if n == name then + index = i + end + end + table.remove(inventory_plus.buttons[player_name], index) +end + +-- set_inventory_formspec +inventory_plus.set_inventory_formspec = function(player,formspec) + if minetest.setting_getbool("creative_mode") then + -- if creative mode is on then wait a bit + minetest.after(0.01,function() + player:set_inventory_formspec(formspec) + end) + else + player:set_inventory_formspec(formspec) + end +end + +-- get_formspec +inventory_plus.get_formspec = function(player,page) + local get_buttons = function(ox,oy,mx) -- origin x, origin y, max x + if not inventory_plus.buttons[player:get_player_name()] then + return "" + end + local formspec = "" + local x,y=ox,oy + for _, i in ipairs(inventory_plus.buttons[player:get_player_name()]) do + formspec = formspec .. "image_button["..x..","..y..";1,1;inventory_plus_"..i..".png;"..i..";]" + x=x+1 + if x >= ox+mx then + y = y+1 + x = ox + end + end + return formspec + end + -- craft page + if page=="main" then + if minetest.setting_getbool("creative_mode") then + return player:get_inventory_formspec() + .. get_buttons(6,0,2) + else + return inventory_plus.inventory[player:get_player_name()] + .. get_buttons(0,0,3) + end + end +end + +-- register_on_joinplayer +minetest.register_on_joinplayer(function(player) + if inventory_plus.inventory[player:get_player_name()] == nil then + inventory_plus.inventory[player:get_player_name()] = player:get_inventory_formspec() + end + minetest.after(1,function() + inventory_plus.set_inventory_formspec(player,inventory_plus.get_formspec(player, inventory_plus.default)) + end) +end) + +-- register_on_player_receive_fields +minetest.register_on_player_receive_fields(function(player, formname, fields) + -- main + if fields.main then + if minetest.setting_getbool("creative_mode") then + minetest.after(0.01,function() + inventory_plus.set_inventory_formspec(player, inventory_plus.get_formspec(player,"main")) + end) + else + inventory_plus.set_inventory_formspec(player, inventory_plus.get_formspec(player,"main")) + end + return + end + if fields.creative_prev or fields.creative_next then + minetest.after(0.01,function() + inventory_plus.set_inventory_formspec(player, inventory_plus.get_formspec(player,"main")) + end) + return + end +end) + +-- log that we started +minetest.log("action", "[MOD]"..minetest.get_current_modname().." -- loaded from "..minetest.get_modpath(minetest.get_current_modname())) diff --git a/mods/inventory_plus/textures/inventory_plus_bags.png b/mods/inventory_plus/textures/inventory_plus_bags.png new file mode 100644 index 0000000..7bc8030 Binary files /dev/null and b/mods/inventory_plus/textures/inventory_plus_bags.png differ diff --git a/mods/inventory_plus/textures/inventory_plus_home_gui.png b/mods/inventory_plus/textures/inventory_plus_home_gui.png new file mode 100644 index 0000000..502b795 Binary files /dev/null and b/mods/inventory_plus/textures/inventory_plus_home_gui.png differ diff --git a/mods/mapgen/functions.lua b/mods/mapgen/functions.lua new file mode 100644 index 0000000..63edc54 --- /dev/null +++ b/mods/mapgen/functions.lua @@ -0,0 +1,298 @@ +local random = math.random + +local function add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + if data[vi] == c_air or data[vi] == c_ignore and snowy_leaves == true then + data[vi] = c_pine_needles + end +end + +local function add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = minetest.get_content_id("mapgen:evergreen_leaves_snowy") + end +end + +local function add_snow(data, vi, c_air, c_ignore, c_snow) + if data[vi] == c_air or data[vi] == c_ignore then + data[vi] = c_snow + end +end + +function mapgen.grow_evergreen(pos, boolsnow) + local x, y, z = pos.x, pos.y, pos.z + local maxy = y + math.random(9, 13) -- Trunk top + + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_pinetree = minetest.get_content_id("mapgen:evergreen_tree") + local c_pine_needles = minetest.get_content_id("mapgen:evergreen_leaves") + local c_snow = minetest.get_content_id("mapgen:snow") + local c_snowblock = minetest.get_content_id("mapgen:snowblock") + local c_dirtsnow = minetest.get_content_id("mapgen:dirt_with_snow") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = x - 3, y = y - 1, z = z - 3}, + {x = x + 3, y = maxy + 3, z = z + 3} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + -- Upper branches layer + local dev = 3 + for yy = maxy - 1, maxy + 1 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if math.random() < 0.95 - dev * 0.05 then + if boolsnow == false then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + elseif boolsnow == true then + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + else + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Centre top nodes + if boolsnow == false then + add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) + add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow, c_pine_needles) + -- Paramat added a pointy top node + elseif boolsnow == true then + add_pine_snow(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) + add_pine_snow(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) + -- Lower branches layer + else + add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) + add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) + end + + local my = 0 + for i = 1, 20 do -- Random 2x2 squares of needles + local xi = x + math.random(-3, 2) + local yy = maxy + math.random(-6, -5) + local zi = z + math.random(-3, 2) + if yy > my then + my = yy + end + for zz = zi, zi+1 do + local vi = a:index(xi, yy, zz) + local via = a:index(xi, yy + 1, zz) + for xx = xi, xi + 1 do + if boolsnow == false then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + elseif boolsnow == true then + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + else + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + end + vi = vi + 1 + via = via + 1 + end + end + end + + local dev = 2 + for yy = my + 1, my + 2 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if random() < 0.95 - dev * 0.05 then + if boolsnow == false then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + elseif boolsnow == true then + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + else + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + dev = 2 + for yy = my - 5, my - 3 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if random() < 0.95 - dev * 0.05 then + if boolsnow == false then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + elseif boolsnow == true then + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + else + add_pine_snow(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Trunk + for yy = y, maxy do + local vi = a:index(x, yy, z) + data[vi] = c_pinetree + end + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end + + +-- + +function mapgen.grow_jungletree(pos) + --[[ + NOTE: Jungletree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + --]] + + local x, y, z = pos.x, pos.y, pos.z + local height = random(8, 12) + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_jungletree = minetest.get_content_id("mapgen:jungle_tree") + local c_jungleleaves = minetest.get_content_id("mapgen:jungle_leaves") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}, + {x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false) + + -- Roots + for z_dist = -1, 1 do + local vi_1 = a:index(x - 1, y - 1, z + z_dist) + local vi_2 = a:index(x - 1, y, z + z_dist) + for x_dist = -1, 1 do + if random(1, 3) >= 2 then + if data[vi_1] == c_air or data[vi_1] == c_ignore then + data[vi_1] = c_jungletree + elseif data[vi_2] == c_air or data[vi_2] == c_ignore then + data[vi_2] = c_jungletree + end + end + vi_1 = vi_1 + 1 + vi_2 = vi_2 + 1 + end + end + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end + +-- + +-- Appletree, jungletree function + +local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid, + height, size, iters, is_apple_tree) + local x, y, z = pos.x, pos.y, pos.z + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_apple = minetest.get_content_id("base:dirt") + + -- Trunk + for y_dist = 0, height - 1 do + local vi = a:index(x, y + y_dist, z) + local node_id = data[vi] + if y_dist == 0 or node_id == c_air or node_id == c_ignore + or node_id == leaves_cid then + data[vi] = tree_cid + end + end + + -- Force leaves near the trunk + for z_dist = -1, 1 do + for y_dist = -size, 1 do + local vi = a:index(x - 1, y + height + y_dist, z + z_dist) + for x_dist = -1, 1 do + if data[vi] == c_air or data[vi] == c_ignore then + if is_apple_tree and random(1, 8) == 1 then + data[vi] = c_apple + else + data[vi] = leaves_cid + end + end + vi = vi + 1 + end + end + end + + -- Randomly add leaves in 2x2x2 clusters. + for i = 1, iters do + local clust_x = x + random(-size, size - 1) + local clust_y = y + height + random(-size, 0) + local clust_z = z + random(-size, size - 1) + + for xi = 0, 1 do + for yi = 0, 1 do + for zi = 0, 1 do + local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi) + if data[vi] == c_air or data[vi] == c_ignore then + if is_apple_tree and random(1, 8) == 1 then + data[vi] = c_apple + else + data[vi] = leaves_cid + end + end + end + end + end + end +end + +-- Appletree + +function mapgen.grow_tree(pos, is_apple_tree, trunk_node, leaves_node) + --[[ + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + --]] + + local x, y, z = pos.x, pos.y, pos.z + local height = random(4, 5) + local c_tree = minetest.get_content_id(trunk_node) + local c_leaves = minetest.get_content_id(leaves_node) + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = pos.x - 2, y = pos.y, z = pos.z - 2}, + {x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree) + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end \ No newline at end of file diff --git a/mods/mapgen/init.lua b/mods/mapgen/init.lua index d49371f..b575ea8 100644 --- a/mods/mapgen/init.lua +++ b/mods/mapgen/init.lua @@ -1,11 +1,13 @@ --init.lua +mapgen = {} + minetest.clear_registered_biomes() dofile(minetest.get_modpath("mapgen").."/mapgen.lua") dofile(minetest.get_modpath("mapgen").."/nodes.lua") dofile(minetest.get_modpath("mapgen").."/flowers.lua") - +dofile(minetest.get_modpath("mapgen").."/functions.lua") minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") minetest.register_alias("mapgen_water_source", "mapgen:water_source") @@ -470,11 +472,89 @@ minetest.register_on_generated(function(minp, maxp, seed) vm:calc_lighting() vm:update_liquids() vm:write_to_map() - - local geninfo = string.format("node randomisation done after: %.2fs", os.clock() - timer) - print(geninfo) -end) + local geninfo = string.format("node randomisation done after: %.2fs", os.clock() - timer) + print(geninfo) +end) + +-- generate trees + +minetest.register_node("mapgen:mg_birch_sapling", { + description = "Impossible to get node.", + drawtype = "airlike", + paramtype = "light", + tiles = {"xfences_space.png"}, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node("mapgen:mg_cherry_sapling", { + description = "Impossible to get node.", + drawtype = "airlike", + paramtype = "light", + tiles = {"xfences_space.png"}, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node("mapgen:mg_oak_sapling", { + description = "Impossible to get node.", + drawtype = "airlike", + paramtype = "light", + tiles = {"xfences_space.png"}, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node("mapgen:mg_evergreen_sapling", { + description = "Impossible to get node.", + drawtype = "airlike", + paramtype = "light", + tiles = {"xfences_space.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local c_mg_oak_sapling = minetest.get_content_id("mapgen:mg_oak_sapling") +local c_mg_cherry_sapling = minetest.get_content_id("mapgen:mg_cherry_sapling") +local c_mg_birch_sapling = minetest.get_content_id("mapgen:mg_birch_sapling") +local c_mg_evergreen_sapling = minetest.get_content_id("mapgen:mg_evergreen_sapling") +local c_mg_evergreen_snow = minetest.get_content_id("mapgen:mg_evergreen_snow") + +minetest.register_on_generated(function(minp, maxp, seed) + local timer = os.clock() + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local data = vm:get_data() + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + local trees_grown = 0 + for z=minp.z, maxp.z, 1 do + for y=minp.y, maxp.y, 1 do + for x=minp.x, maxp.x, 1 do + local p_pos = area:index(x,y,z) + local content_id = data[p_pos] + if content_id == c_mg_birch_sapling then + mapgen.grow_tree({x=x, y=y, z=z}, false, "mapgen:birch_tree", "mapgen:birch_leaves") + trees_grown = trees_grown + 1 + elseif content_id == c_mg_cherry_sapling then + mapgen.grow_tree({x=x, y=y, z=z}, false, "mapgen:cherry_tree", "mapgen:cherry_blossom_leaves") + trees_grown = trees_grown + 1 + elseif content_id == c_mg_evergreen_sapling then + mapgen.grow_evergreen({x=x, y=y, z=z}, false) + trees_grown = trees_grown + 1 + elseif content_id == c_mg_evergreen_snow then + mapgen.grow_evergreen({x=x, y=y, z=z}, true) + trees_grown = trees_grown + 1 + elseif content_id == c_mg_oak_sapling then + mapgen.grow_tree({x=x, y=y, z=z}, false, "mapgen:oak_log_tree", "mapgen:oak_leaves") + trees_grown = trees_grown + 1 + else + -- nope + end + end + end + end + local geninfo = string.format(" trees grown after: %.2fs", os.clock() - timer) + print (trees_grown..geninfo) +end) + +-- abms here + minetest.register_abm({ nodenames = {"mapgen:dirt"}, neighbors = {"mapgen:grass", "mapgen:grass_1", "mapgen:grass_2", "mapgen:grass_3", "mapgen:grass_4"}, @@ -559,7 +639,7 @@ minetest.register_abm({ minetest.remove_node({x=pos.x, y=pos.y, z=pos.z}) - minetest.place_schematic({x=pos.x-2, y=pos.y-1, z=pos.z-2}, minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", "random", {{"base:leaves", "mapgen:oak_leaves"}, {"base:tree", "mapgen:oak_log_tree"}, {"base:dirt", "mapgen:dirt"}}, false) + mapgen.grow_tree(pos, false, "mapgen:oak_log_tree", "mapgen:oak_leaves") end, }) @@ -578,7 +658,7 @@ minetest.register_abm({ minetest.remove_node({x=pos.x, y=pos.y, z=pos.z}) - minetest.place_schematic({x=pos.x-2, y=pos.y-1, z=pos.z-2}, minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", "random", {{"base:leaves", "mapgen:birch_leaves"}, {"base:tree", "mapgen:birch_tree"}, {"base:dirt", "mapgen:dirt"}}, false) + mapgen.grow_tree(pos, false, "mapgen:birch_tree", "mapgen:birch_leaves") end, }) @@ -597,13 +677,13 @@ minetest.register_abm({ minetest.remove_node({x=pos.x, y=pos.y, z=pos.z}) - minetest.place_schematic({x=pos.x-2, y=pos.y-1, z=pos.z-2}, minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", "random", {{"base:leaves", "mapgen:cherry_blossom_leaves"}, {"base:tree", "mapgen:cherry_tree"}, {"base:dirt", "mapgen:dirt"}}, false) + mapgen.grow_tree(pos, false, "mapgen:cherry_tree", "mapgen:cherry_blossom_leaves") end, }) minetest.register_abm({ nodenames = {"mapgen:evergreen_sapling"}, - interval = 80, + interval = 80*3, chance = 3, action = function(pos, node) @@ -620,7 +700,7 @@ minetest.register_abm({ else minetest.remove_node({x=pos.x, y=pos.y, z=pos.z}) - minetest.place_schematic({x=pos.x-2, y=pos.y-1, z=pos.z-2}, minetest.get_modpath("mapgen").."/schematics/mapgen_evergreen.mts", "random", {{"base:leaves", "mapgen:evergreen_leaves"}, {"base:tree", "mapgen:evergreen_tree"}, {"base:dirt", "mapgen:dirt"}}, false) + mapgen.grow_evergreen(pos, true) end end, }) diff --git a/mods/mapgen/mapgen.lua b/mods/mapgen/mapgen.lua index 08fe2c9..d1befe5 100644 --- a/mods/mapgen/mapgen.lua +++ b/mods/mapgen/mapgen.lua @@ -410,14 +410,13 @@ minetest.register_biome({ }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:deathly_grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", + decoration = {"mapgen:deathly_sapling",}, sidelen = 8, fill_ratio = 0.034, biomes = {"deathly_forest"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:deathly_leaves", ["base:tree"] = "mapgen:deathly_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ @@ -483,47 +482,43 @@ minetest.register_decoration({ }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", + decoration = "mapgen:mg_oak_sapling", sidelen = 8, fill_ratio = 0.034, biomes = {"oak_forest", "floral_oak_forest", "floral_oakg_forest", "v6_forest"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:oak_leaves", ["base:tree"] = "mapgen:oak_log_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", + decoration = "mapgen:mg_cherry_sapling", sidelen = 8, fill_ratio = 0.034, biomes = {"cherry_blossom_forest", "v6_forest"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:cherry_blossom_leaves", ["base:tree"] = "mapgen:cherry_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:snowy_grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_evergreen.mts", + decoration = "mapgen:mg_evergreen_snow", sidelen = 8, fill_ratio = 0.051, biomes = {"taiga"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:evergreen_leaves_snowy", ["base:tree"] = "mapgen:evergreen_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_evergreen.mts", + decoration = "mapgen:mg_evergreen_sapling", sidelen = 8, fill_ratio = 0.061, biomes = {"evergreens_forest", "v6_forest"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:evergreen_leaves", ["base:tree"] = "mapgen:evergreen_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ @@ -547,14 +542,13 @@ minetest.register_decoration({ }) minetest.register_decoration({ - deco_type = "schematic", + deco_type = "simple", place_on = "mapgen:grass", - schematic = minetest.get_modpath("mapgen").."/schematics/mapgen_oak_tree.mts", + decoration = "mapgen:mg_birch_sapling", sidelen = 8, fill_ratio = 0.030, biomes = {"birch_forest", "birch_forest_floral", "birch_forest_grassy", "v6_forest"}, - flags = "place_center_x, place_center_z", - replacements = {["base:leaves"] = "mapgen:birch_leaves", ["base:tree"] = "mapgen:birch_tree", ["base:dirt"] = "mapgen:dirt"}, + height = 1, }) minetest.register_decoration({ diff --git a/mods/zcg/depends.txt b/mods/zcg/depends.txt new file mode 100644 index 0000000..eb98431 --- /dev/null +++ b/mods/zcg/depends.txt @@ -0,0 +1 @@ +inventory_plus diff --git a/mods/zcg/init.lua b/mods/zcg/init.lua new file mode 100644 index 0000000..6ee1b6e --- /dev/null +++ b/mods/zcg/init.lua @@ -0,0 +1,209 @@ +-- ZCG mod for minetest +-- See README for more information +-- Released by Zeg9 under WTFPL + +zcg = {} + +zcg.users = {} +zcg.crafts = {} +zcg.itemlist = {} + +zcg.items_in_group = function(group) + local items = {} + local ok = true + for name, item in pairs(minetest.registered_items) do + -- the node should be in all groups + ok = true + for _, g in ipairs(group:split(',')) do + if not item.groups[g] then + ok = false + end + end + if ok then table.insert(items,name) end + end + return items +end + +local table_copy = function(table) + out = {} + for k,v in pairs(table) do + out[k] = v + end + return out +end + +zcg.add_craft = function(input, output, groups) + if minetest.get_item_group(output, "not_in_craft_guide") > 0 then + return + end + if not groups then groups = {} end + local c = {} + c.width = input.width + c.type = input.type + c.items = input.items + if c.items == nil then return end + for i, item in pairs(c.items) do + if item:sub(0,6) == "group:" then + local groupname = item:sub(7) + if groups[groupname] ~= nil then + c.items[i] = groups[groupname] + else + for _, gi in ipairs(zcg.items_in_group(groupname)) do + local g2 = groups + g2[groupname] = gi + zcg.add_craft({ + width = c.width, + type = c.type, + items = table_copy(c.items) + }, output, g2) -- it is needed to copy the table, else groups won't work right + end + return + end + end + end + if c.width == 0 then c.width = 3 end + table.insert(zcg.crafts[output],c) +end + +zcg.load_crafts = function(name) + zcg.crafts[name] = {} + local _recipes = minetest.get_all_craft_recipes(name) + if _recipes then + for i, recipe in ipairs(_recipes) do + if (recipe and recipe.items and recipe.type) then + zcg.add_craft(recipe, name) + end + end + end + if zcg.crafts[name] == nil or #zcg.crafts[name] == 0 then + zcg.crafts[name] = nil + else + table.insert(zcg.itemlist,name) + end +end + +zcg.need_load_all = true + +zcg.load_all = function() + print("Loading all crafts, this may take some time...") + local i = 0 + for name, item in pairs(minetest.registered_items) do + if (name and name ~= "") then + zcg.load_crafts(name) + end + i = i+1 + end + table.sort(zcg.itemlist) + zcg.need_load_all = false + print("All crafts loaded !") +end + +zcg.formspec = function(pn) + if zcg.need_load_all then zcg.load_all() end + page = zcg.users[pn].page + alt = zcg.users[pn].alt + current_item = zcg.users[pn].current_item + local formspec = "size[8,7.5]" + .. "button[0,0;2,.5;main;Back]" + if zcg.users[pn].history.index > 1 then + formspec = formspec .. "image_button[0,1;1,1;zcg_previous.png;zcg_previous;;false;false;zcg_previous_press.png]" + else + formspec = formspec .. "image[0,1;1,1;zcg_previous_inactive.png]" + end + if zcg.users[pn].history.index < #zcg.users[pn].history.list then + formspec = formspec .. "image_button[1,1;1,1;zcg_next.png;zcg_next;;false;false;zcg_next_press.png]" + else + formspec = formspec .. "image[1,1;1,1;zcg_next_inactive.png]" + end + -- Show craft recipe + if current_item ~= "" then + if zcg.crafts[current_item] then + if alt > #zcg.crafts[current_item] then + alt = #zcg.crafts[current_item] + end + if alt > 1 then + formspec = formspec .. "button[7,0;1,1;zcg_alt:"..(alt-1)..";^]" + end + if alt < #zcg.crafts[current_item] then + formspec = formspec .. "button[7,2;1,1;zcg_alt:"..(alt+1)..";v]" + end + local c = zcg.crafts[current_item][alt] + if c then + local x = 3 + local y = 0 + for i, item in pairs(c.items) do + formspec = formspec .. "item_image_button["..((i-1)%c.width+x)..","..(math.floor((i-1)/c.width+y))..";1,1;"..item..";zcg:"..item..";]" + end + if c.type == "normal" or c.type == "cooking" then + formspec = formspec .. "image[6,2;1,1;zcg_method_"..c.type..".png]" + else -- we don't have an image for other types of crafting + formspec = formspec .. "label[0,2;Method: "..c.type.."]" + end + formspec = formspec .. "image[6,1;1,1;zcg_craft_arrow.png]" + formspec = formspec .. "item_image_button[7,1;1,1;"..zcg.users[pn].current_item..";;]" + end + end + end + + -- Node list + local npp = 8*3 -- nodes per page + local i = 0 -- for positionning buttons + local s = 0 -- for skipping pages + for _, name in ipairs(zcg.itemlist) do + if s < page*npp then s = s+1 else + if i >= npp then break end + formspec = formspec .. "item_image_button["..(i%8)..","..(math.floor(i/8)+3.5)..";1,1;"..name..";zcg:"..name..";]" + i = i+1 + end + end + if page > 0 then + formspec = formspec .. "button[0,7;1,.5;zcg_page:"..(page-1)..";<<]" + end + if i >= npp then + formspec = formspec .. "button[1,7;1,.5;zcg_page:"..(page+1)..";>>]" + end + formspec = formspec .. "label[2,6.85;Page "..(page+1).."/"..(math.floor(#zcg.itemlist/npp+1)).."]" -- The Y is approximatively the good one to have it centered vertically... + return formspec.."listcolors[#664620;#f9ca93;#ffffff;#c69c6a;#ffffff]".."background[-0.5,-0.65;9,8.75;".."inventory.png".."]" +end + +minetest.register_on_joinplayer(function(player) + inventory_plus.register_button(player,"zcg","Craft guide") +end) + +minetest.register_on_player_receive_fields(function(player,formname,fields) + pn = player:get_player_name(); + if zcg.users[pn] == nil then zcg.users[pn] = {current_item = "", alt = 1, page = 0, history={index=0,list={}}} end + if fields.zcg then + inventory_plus.set_inventory_formspec(player, zcg.formspec(pn)) + return + elseif fields.zcg_previous then + if zcg.users[pn].history.index > 1 then + zcg.users[pn].history.index = zcg.users[pn].history.index - 1 + zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index] + inventory_plus.set_inventory_formspec(player,zcg.formspec(pn)) + end + elseif fields.zcg_next then + if zcg.users[pn].history.index < #zcg.users[pn].history.list then + zcg.users[pn].history.index = zcg.users[pn].history.index + 1 + zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index] + inventory_plus.set_inventory_formspec(player,zcg.formspec(pn)) + end + end + for k, v in pairs(fields) do + if (k:sub(0,4)=="zcg:") then + local ni = k:sub(5) + if zcg.crafts[ni] then + zcg.users[pn].current_item = ni + table.insert(zcg.users[pn].history.list, ni) + zcg.users[pn].history.index = #zcg.users[pn].history.list + inventory_plus.set_inventory_formspec(player,zcg.formspec(pn)) + end + elseif (k:sub(0,9)=="zcg_page:") then + zcg.users[pn].page = tonumber(k:sub(10)) + inventory_plus.set_inventory_formspec(player,zcg.formspec(pn)) + elseif (k:sub(0,8)=="zcg_alt:") then + zcg.users[pn].alt = tonumber(k:sub(9)) + inventory_plus.set_inventory_formspec(player,zcg.formspec(pn)) + end + end +end) diff --git a/mods/zcg/textures/inventory_plus_zcg.png b/mods/zcg/textures/inventory_plus_zcg.png new file mode 100644 index 0000000..f0101f2 Binary files /dev/null and b/mods/zcg/textures/inventory_plus_zcg.png differ diff --git a/mods/zcg/textures/zcg_craft_arrow.png b/mods/zcg/textures/zcg_craft_arrow.png new file mode 100644 index 0000000..e121c2b Binary files /dev/null and b/mods/zcg/textures/zcg_craft_arrow.png differ diff --git a/mods/zcg/textures/zcg_method_cooking.png b/mods/zcg/textures/zcg_method_cooking.png new file mode 100644 index 0000000..8779cf6 Binary files /dev/null and b/mods/zcg/textures/zcg_method_cooking.png differ diff --git a/mods/zcg/textures/zcg_method_normal.png b/mods/zcg/textures/zcg_method_normal.png new file mode 100644 index 0000000..27671f9 Binary files /dev/null and b/mods/zcg/textures/zcg_method_normal.png differ diff --git a/mods/zcg/textures/zcg_next.png b/mods/zcg/textures/zcg_next.png new file mode 100644 index 0000000..d794883 Binary files /dev/null and b/mods/zcg/textures/zcg_next.png differ diff --git a/mods/zcg/textures/zcg_next_inactive.png b/mods/zcg/textures/zcg_next_inactive.png new file mode 100644 index 0000000..3aea097 Binary files /dev/null and b/mods/zcg/textures/zcg_next_inactive.png differ diff --git a/mods/zcg/textures/zcg_next_press.png b/mods/zcg/textures/zcg_next_press.png new file mode 100644 index 0000000..bbe0c8a Binary files /dev/null and b/mods/zcg/textures/zcg_next_press.png differ diff --git a/mods/zcg/textures/zcg_previous.png b/mods/zcg/textures/zcg_previous.png new file mode 100644 index 0000000..cc54f15 Binary files /dev/null and b/mods/zcg/textures/zcg_previous.png differ diff --git a/mods/zcg/textures/zcg_previous_inactive.png b/mods/zcg/textures/zcg_previous_inactive.png new file mode 100644 index 0000000..1d559b2 Binary files /dev/null and b/mods/zcg/textures/zcg_previous_inactive.png differ diff --git a/mods/zcg/textures/zcg_previous_press.png b/mods/zcg/textures/zcg_previous_press.png new file mode 100644 index 0000000..9cb2681 Binary files /dev/null and b/mods/zcg/textures/zcg_previous_press.png differ