diff --git a/game_api.txt b/game_api.txt index a32f8d5c..d3330e5f 100644 --- a/game_api.txt +++ b/game_api.txt @@ -78,6 +78,12 @@ The doors mod allows modders to register custom doors and trapdoors. * `name` Name for trapdoor * `def` See [#Trapdoor definition] +`doors.register_fencegate(name, def)` + + * Registers new fence gate + * `name` Name for fence gate + * `def` See [#Fence gate definition] + `doors.get(pos)` * `pos` A position as a table, e.g `{x = 1, y = 1, z = 1}` @@ -119,6 +125,14 @@ The doors mod allows modders to register custom doors and trapdoors. sound_close = sound play for close door, -- optional protected = false, -- If true, only placer can open the door (locked for others) +###Fence gate definition + + description = "Wooden Fence Gate", + texture = "default_wood.png", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults(), -- optional + Fence API --------- Allows creation of new fences with "fencelike" drawtype. diff --git a/mods/beds/api.lua b/mods/beds/api.lua index be3cb97e..e2dd7edf 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -44,23 +44,42 @@ function beds.register_bed(name, def) fixed = def.selectionbox, }, - after_place_node = function(pos, placer, itemstack) - local n = minetest.get_node_or_nil(pos) - if not n or not n.param2 then - minetest.remove_node(pos) - return true + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local pos + if minetest.registered_items[minetest.get_node(under).name].buildable_to then + pos = under + else + pos = pointed_thing.above end - local dir = minetest.facedir_to_dir(n.param2) - local p = vector.add(pos, dir) - local n2 = minetest.get_node_or_nil(p) - local def = n2 and minetest.registered_items[n2.name] - if not def or not def.buildable_to then - minetest.remove_node(pos) - return true + + if minetest.is_protected(pos, placer:get_player_name()) and + not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(pos, placer:get_player_name()) + return itemstack end - minetest.set_node(p, {name = n.name:gsub("%_bottom", "_top"), param2 = n.param2}) - return false - end, + + local dir = minetest.dir_to_facedir(placer:get_look_dir()) + local botpos = vector.add(pos, minetest.facedir_to_dir(dir)) + + if minetest.is_protected(botpos, placer:get_player_name()) and + not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(botpos, placer:get_player_name()) + return itemstack + end + + if not minetest.registered_nodes[minetest.get_node(botpos).name].buildable_to then + return itemstack + end + + minetest.set_node(pos, {name = name .. "_bottom", param2 = dir}) + minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) + + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + return itemstack + end, on_destruct = function(pos) destruct_bed(pos, 1) @@ -96,9 +115,10 @@ function beds.register_bed(name, def) return false end node.param2 = new_param2 - minetest.swap_node(pos, node) - minetest.remove_node(p) - minetest.set_node(newp, {name = node.name:gsub("%_bottom", "_top"), param2 = new_param2}) + -- do not remove_node here - it will trigger destroy_bed() + minetest.set_node(p, {name = "air"}) + minetest.set_node(pos, node) + minetest.set_node(newp, {name = name .. "_top", param2 = new_param2}) return true end, }) diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua index 14ec75bf..f3980a7a 100644 --- a/mods/beds/spawns.lua +++ b/mods/beds/spawns.lua @@ -18,8 +18,8 @@ function beds.read_spawns() repeat local x = input:read("*n") if x == nil then - break - end + break + end local y = input:read("*n") local z = input:read("*n") local name = input:read("*l") @@ -52,7 +52,10 @@ function beds.set_spawns() for name,_ in pairs(beds.player) do local player = minetest.get_player_by_name(name) local p = player:getpos() - beds.spawn[name] = p + -- but don't change spawn location if borrowing a bed + if not minetest.is_protected(p, name) then + beds.spawn[name] = p + end end beds.save_spawns() end diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 32163d19..018485a6 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -12,17 +12,19 @@ local function is_owner(pos, name) end bones.bones_formspec = - "size[8,9]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - "list[current_name;main;0,0.3;8,4;]".. - "list[current_player;main;0,4.85;8,1;]".. - "list[current_player;main;0,6.08;8,3;8]".. + "size[8,9]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. default.get_hotbar_bg(0,4.85) -local share_bones_time = tonumber(minetest.setting_get("share_bones_time") or 1200) -local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early") or (share_bones_time/4)) +local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200 +local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4 minetest.register_node("bones:bones", { description = "Bones", diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 01163707..c842efd3 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -6,15 +6,15 @@ local player_inventory = {} -- Create detached creative inventory after loading all mods creative.init_creative_inventory = function(player) local player_name = player:get_player_name() - player_inventory[player_name] = {} player_inventory[player_name].size = 0 - player_inventory[player_name].filter = nil + player_inventory[player_name].filter = "" player_inventory[player_name].start_i = 1 + player_inventory[player_name].tab_id = 2 - local inv = minetest.create_detached_inventory("creative_" .. player_name, { + minetest.create_detached_inventory("creative_" .. player_name, { allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if minetest.setting_getbool("creative_mode") then + if minetest.setting_getbool("creative_mode") and not to_list == "main" then return count else return 0 @@ -35,16 +35,17 @@ creative.init_creative_inventory = function(player) on_put = function(inv, listname, index, stack, player) end, on_take = function(inv, listname, index, stack, player) - --print(player:get_player_name().." takes item from creative inventory; listname="..dump(listname)..", index="..dump(index)..", stack="..dump(stack)) + local player_name, stack_name = player:get_player_name(), stack:get_name() + --print(player_name .. " takes item from creative inventory; listname = " .. listname .. ", index = " .. index .. ", stack = " .. dump(stack:to_table())) if stack then - minetest.log("action", player:get_player_name().." takes "..dump(stack:get_name()).." from creative inventory") - --print("stack:get_name()="..dump(stack:get_name())..", stack:get_count()="..dump(stack:get_count())) + minetest.log("action", player_name .. " takes " .. stack_name .. " from creative inventory") + --print("Stack name: " .. stack_name .. ", Stack count: " .. stack:get_count()) end end, }) - creative.update_creative_inventory(player_name, nil, 2) - --print("creative inventory size: "..dump(player_inventory[player_name].size)) + creative.update_creative_inventory(player_name) + --print("creative inventory size: " .. player_inventory[player_name].size) end local function tab_category(tab_id) @@ -60,23 +61,24 @@ local function tab_category(tab_id) return id_category[tab_id] or id_category[2] end -function creative.update_creative_inventory(player_name, filter, tab_id) +function creative.update_creative_inventory(player_name) local creative_list = {} - local inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + local inv = player_inventory[player_name] - for name, def in pairs(tab_category(tab_id)) do + for name, def in pairs(tab_category(inv.tab_id)) do if not (def.groups.not_in_creative_inventory == 1) and def.description and def.description ~= "" and - (not filter or def.name:find(filter, 1, true) or - def.description:lower():find(filter, 1, true)) then + (def.name:find(inv.filter, 1, true) or + def.description:lower():find(inv.filter, 1, true)) then creative_list[#creative_list+1] = name end end table.sort(creative_list) - inv:set_size("main", #creative_list) - inv:set_list("main", creative_list) - player_inventory[player_name].size = #creative_list + player_inv:set_size("main", #creative_list) + player_inv:set_list("main", creative_list) + inv.size = #creative_list end -- Create the trash field @@ -90,18 +92,17 @@ local trash = minetest.create_detached_inventory("creative_trash", { return 0 end end, - on_put = function(inv, listname, index, stack, player) - inv:set_stack(listname, index, "") + on_put = function(inv, listname) + inv:set_list(listname, {}) end, }) trash:set_size("main", 1) -creative.set_creative_formspec = function(player, start_i, pagenum, tab_id) +creative.set_creative_formspec = function(player, start_i) local player_name = player:get_player_name() - local filter = player_inventory[player_name].filter or "" - pagenum = math.floor(pagenum) - local pagemax = math.floor((player_inventory[player_name].size - 1) / (3*8) + 1) - tab_id = tab_id or 2 + local inv = player_inventory[player_name] + local pagenum = math.floor(start_i / (3*8) + 1) + local pagemax = math.ceil(inv.size / (3*8)) player:set_inventory_formspec([[ size[8,8.6] @@ -109,6 +110,7 @@ creative.set_creative_formspec = function(player, start_i, pagenum, tab_id) list[current_player;main;0,4.7;8,1;] list[current_player;main;0,5.85;8,3;8] list[detached:creative_trash;main;4,3.3;1,1;] + listring[] tablecolumns[color;text;color;text] tableoptions[background=#00000000;highlight=#00000000;border=false] button[5.4,3.2;0.8,0.9;creative_prev;<] @@ -119,12 +121,12 @@ creative.set_creative_formspec = function(player, start_i, pagenum, tab_id) tooltip[creative_clear;Reset] listring[current_player;main] ]] .. - "field[0.3,3.5;2.2,1;creative_filter;;".. filter .."]".. - "listring[detached:creative_".. player_name ..";main]".. - "tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;".. tostring(tab_id) ..";true;false]".. - "list[detached:creative_".. player_name ..";main;0,0;8,3;".. tostring(start_i) .."]".. - "table[6.05,3.35;1.15,0.5;pagenum;#FFFF00,".. tostring(pagenum) ..",#FFFFFF,/ ".. tostring(pagemax) .."]".. - default.get_hotbar_bg(0,4.7).. + "field[0.3,3.5;2.2,1;creative_filter;;" .. inv.filter .. "]" .. + "listring[detached:creative_" .. player_name .. ";main]" .. + "tabheader[0,0;creative_tabs;Crafting,All,Nodes,Tools,Items;" .. tostring(inv.tab_id) .. ";true;false]" .. + "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. + "table[6.05,3.35;1.15,0.5;pagenum;#FFFF00," .. tostring(pagenum) .. ",#FFFFFF,/ " .. tostring(pagemax) .. "]" .. + default.get_hotbar_bg(0,4.7) .. default.gui_bg .. default.gui_bg_img .. default.gui_slots ) end @@ -143,7 +145,7 @@ creative.set_crafting_formspec = function(player) listring[current_player;main] listring[current_player;craft] ]] .. - default.get_hotbar_bg(0,4.7).. + default.get_hotbar_bg(0,4.7) .. default.gui_bg .. default.gui_bg_img .. default.gui_slots ) end @@ -154,7 +156,7 @@ minetest.register_on_joinplayer(function(player) return end creative.init_creative_inventory(player) - creative.set_creative_formspec(player, 0, 1, 2) + creative.set_creative_formspec(player, 0) end) minetest.register_on_player_receive_fields(function(player, formname, fields) @@ -163,70 +165,72 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end local player_name = player:get_player_name() - local formspec = player:get_inventory_formspec() - local filter = formspec:match("creative_filter;;([%w_:]+)") or "" - local start_i = formspec:match("list%[.-".. player_name ..";.-;(%d+)%]") - local tab_id = tonumber(formspec:match("tabheader%[.-;(%d+)%;")) - local inv_size = player_inventory[player_name].size - start_i = tonumber(start_i) or 0 + local inv = player_inventory[player_name] if fields.quit then - if tab_id == 1 then + if inv.tab_id == 1 then creative.set_crafting_formspec(player) end elseif fields.creative_tabs then local tab = tonumber(fields.creative_tabs) + inv.tab_id = tab + if tab == 1 then creative.set_crafting_formspec(player) else - creative.update_creative_inventory(player_name, filter, tab) - creative.set_creative_formspec(player, 0, 1, tab) + creative.update_creative_inventory(player_name) + creative.set_creative_formspec(player, 0) end elseif fields.creative_clear then - player_inventory[player_name].filter = "" - creative.update_creative_inventory(player_name, nil, tab_id) - creative.set_creative_formspec(player, 0, 1, tab_id) + inv.filter = "" + creative.update_creative_inventory(player_name) + creative.set_creative_formspec(player, 0) elseif fields.creative_search then - local lowstr = fields.creative_filter:lower() - player_inventory[player_name].filter = lowstr - creative.update_creative_inventory(player_name, lowstr, tab_id) - creative.set_creative_formspec(player, 0, 1, tab_id) + inv.filter = fields.creative_filter:lower() + creative.update_creative_inventory(player_name) + creative.set_creative_formspec(player, 0) else + local formspec = player:get_inventory_formspec() + local start_i = formspec:match("list%[.-" .. player_name .. ";.-;(%d+)%]") + start_i = tonumber(start_i) or 0 + if fields.creative_prev then start_i = start_i - 3*8 if start_i < 0 then - start_i = inv_size - (inv_size % (3*8)) - if inv_size == start_i then - start_i = math.max(0, inv_size - (3*8)) + start_i = inv.size - (inv.size % (3*8)) + if inv.size == start_i then + start_i = math.max(0, inv.size - (3*8)) end end elseif fields.creative_next then start_i = start_i + 3*8 - if start_i >= inv_size then + if start_i >= inv.size then start_i = 0 end end - creative.set_creative_formspec(player, start_i, start_i / (3*8) + 1, tab_id) + creative.set_creative_formspec(player, start_i) end end) if minetest.setting_getbool("creative_mode") then local digtime = 0.5 + local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 3} + minetest.register_item(":", { type = "none", wield_image = "wieldhand.png", - wield_scale = {x=1, y=1, z=2.5}, + wield_scale = {x = 1, y = 1, z = 2.5}, range = 10, tool_capabilities = { full_punch_interval = 0.5, max_drop_level = 3, groupcaps = { - crumbly = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3}, - cracky = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3}, - snappy = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3}, - choppy = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3}, - oddly_breakable_by_hand = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3}, + crumbly = caps, + cracky = caps, + snappy = caps, + choppy = caps, + oddly_breakable_by_hand = caps, }, damage_groups = {fleshy = 10}, } diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua index 31d85c9b..8b8a6d35 100644 --- a/mods/default/craftitems.lua +++ b/mods/default/craftitems.lua @@ -11,14 +11,24 @@ minetest.register_craftitem("default:paper", { inventory_image = "default_paper.png", }) -local function book_on_use(itemstack, user, pointed_thing) +local function book_on_use(itemstack, user) local player_name = user:get_player_name() local data = minetest.deserialize(itemstack:get_metadata()) - local title, text, owner = "", "", player_name + local formspec, title, text, owner = "", "", "", player_name + local page, page_max, cpp = 1, 1, 650 + if data then - title, text, owner = data.title, data.text, data.owner + title = data.title + text = data.text + owner = data.owner + + if data.page then + page = data.page + page_max = data.page_max + cpp = data.chars_per_page + end end - local formspec + if owner == player_name then formspec = "size[8,8]" .. default.gui_bg .. default.gui_bg_img .. @@ -31,48 +41,81 @@ local function book_on_use(itemstack, user, pointed_thing) formspec = "size[8,8]" .. default.gui_bg .. default.gui_bg_img .. "label[0.5,0.5;by " .. owner .. "]" .. - "label[0.5,0;" .. minetest.formspec_escape(title) .. "]" .. - "textarea[0.5,1.5;7.5,7;text;;" .. - minetest.formspec_escape(text) .. "]" + "tablecolumns[color;text]" .. + "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. + "table[0.4,0;7,0.5;title;#FFFF00," .. minetest.formspec_escape(title) .. "]" .. + "textarea[0.5,1.5;7.5,7;;" .. minetest.formspec_escape(text:sub( + (cpp * page) - cpp, cpp * page)) .. ";]" .. + "button[2.4,7.6;0.8,0.8;book_prev;<]" .. + "label[3.2,7.7;Page " .. page .. " of " .. page_max .. "]" .. + "button[4.9,7.6;0.8,0.8;book_next;>]" end - minetest.show_formspec(user:get_player_name(), "default:book", formspec) + + minetest.show_formspec(player_name, "default:book", formspec) end -minetest.register_on_player_receive_fields(function(player, form_name, fields) - if form_name ~= "default:book" or not fields.save or - fields.title == "" or fields.text == "" then - return - end +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "default:book" then return end local inv = player:get_inventory() local stack = player:get_wielded_item() - local new_stack, data - if stack:get_name() ~= "default:book_written" then - local count = stack:get_count() - if count == 1 then - stack:set_name("default:book_written") + + if fields.save and fields.title ~= "" and fields.text ~= "" then + local new_stack, data + if stack:get_name() ~= "default:book_written" then + local count = stack:get_count() + if count == 1 then + stack:set_name("default:book_written") + else + stack:set_count(count - 1) + new_stack = ItemStack("default:book_written") + end else - stack:set_count(count - 1) - new_stack = ItemStack("default:book_written") + data = minetest.deserialize(stack:get_metadata()) end - else - data = minetest.deserialize(stack:get_metadata()) - end - if not data then data = {} end - data.title = fields.title - data.text = fields.text - data.owner = player:get_player_name() - local data_str = minetest.serialize(data) - if new_stack then - new_stack:set_metadata(data_str) - if inv:room_for_item("main", new_stack) then - inv:add_item("main", new_stack) + + if not data then data = {} end + data.title = fields.title + data.text = fields.text + data.text_len = fields.text:len() + data.page = 1 + data.chars_per_page = 650 + data.page_max = math.ceil(data.text_len / data.chars_per_page) + data.owner = player:get_player_name() + local data_str = minetest.serialize(data) + + if new_stack then + new_stack:set_metadata(data_str) + if inv:room_for_item("main", new_stack) then + inv:add_item("main", new_stack) + else + minetest.add_item(player:getpos(), new_stack) + end else - minetest.add_item(player:getpos(), new_stack) + stack:set_metadata(data_str) end - else + + player:set_wielded_item(stack) + + elseif fields.book_next or fields.book_prev then + local data = minetest.deserialize(stack:get_metadata()) + if not data.page then return end + + if fields.book_next then + data.page = data.page + 1 + if data.page > data.page_max then + data.page = 1 + end + else + data.page = data.page - 1 + if data.page == 0 then + data.page = data.page_max + end + end + + local data_str = minetest.serialize(data) stack:set_metadata(data_str) + book_on_use(stack, player) end - player:set_wielded_item(stack) end) minetest.register_craftitem("default:book", { diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 29506c40..8e8a3b46 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -40,9 +40,9 @@ end function default.node_sound_sand_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_sand_footstep", gain = 0.2} + {name = "default_sand_footstep", gain = 0.12} table.dug = table.dug or - {name = "default_sand_footstep", gain = 0.4} + {name = "default_sand_footstep", gain = 0.24} table.place = table.place or {name = "default_place_node", gain = 1.0} default.node_sound_defaults(table) diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index 3424a557..4b61518e 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -1204,7 +1204,6 @@ function default.register_decorations() y_max = 31000, schematic = minetest.get_modpath("default").."/schematics/aspen_tree.mts", flags = "place_center_x, place_center_z", - rotation = "random", }) minetest.register_decoration({ diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 5a2e1a3d..ac4ecca4 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -14,7 +14,7 @@ language (for example pinewood and pine wood) the underscore form should be used Stone ----- -(1. Material 2. Cobble variant 3. Brick variant [4. Modified forms]) +(1. Material 2. Cobble variant 3. Brick variant 4. Modified forms) default:stone default:cobble @@ -33,7 +33,7 @@ default:obsidianbrick Soft / Non-Stone ---------------- -(1. Material [2. Modified forms]) +(1. Material 2. Modified forms) default:dirt default:dirt_with_grass @@ -55,7 +55,7 @@ default:ice Trees ----- -(1. Trunk 2. Fabricated trunk 3. Leaves 4. Sapling [5. Fruits]) +(1. Trunk 2. Fabricated trunk 3. Leaves 4. Sapling 5. Fruits) default:tree default:wood @@ -82,9 +82,10 @@ default:aspen_tree default:aspen_wood default:aspen_leaves default:aspen_sapling + Ores ---- -(1. In stone 2. Block) +(1. In stone 2. Blocks) default:stone_with_coal default:coalblock @@ -107,6 +108,7 @@ default:diamondblock Plantlife (non-cubic) --------------------- + default:cactus default:papyrus default:dry_shrub @@ -139,6 +141,7 @@ default:lava_flowing Tools / "Advanced" crafting / Non-"natural" ------------------------------------------- + default:torch default:chest @@ -169,6 +172,7 @@ default:meselamp Misc ---- + default:cloud default:nyancat default:nyancat_rainbow @@ -884,7 +888,7 @@ minetest.register_node("default:cactus", { tiles = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"}, paramtype2 = "facedir", - groups = {snappy = 1, choppy = 3, flammable = 2}, + groups = {snappy = 1, choppy = 3}, sounds = default.node_sound_wood_defaults(), on_place = minetest.rotate_node, }) @@ -942,7 +946,7 @@ minetest.register_node("default:junglegrass", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flammable = 2, flora = 1, attached_node = 1}, + groups = {snappy = 3, flora = 1, attached_node = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", @@ -963,7 +967,7 @@ minetest.register_node("default:grass_1", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flammable = 3, flora = 1, attached_node = 1}, + groups = {snappy = 3, flora = 1, attached_node = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", @@ -992,8 +996,8 @@ for i = 2, 5 do walkable = false, buildable_to = true, drop = "default:grass_1", - groups = {snappy = 3, flammable = 3, flora = 1, - attached_node = 1, not_in_creative_inventory = 1}, + groups = {snappy = 3, flora = 1, attached_node = 1, + not_in_creative_inventory = 1}, sounds = default.node_sound_leaves_defaults(), selection_box = { type = "fixed", @@ -1667,7 +1671,7 @@ end register_sign("wood", "Wooden", { sounds = default.node_sound_wood_defaults(), - groups = {choppy = 2, attached_node = 1, flammable = 2} + groups = {choppy = 2, attached_node = 1, flammable = 2, oddly_breakable_by_hand = 3} }) register_sign("steel", "Steel", { diff --git a/mods/default/trees.lua b/mods/default/trees.lua index c93fdabc..de2452e4 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -403,7 +403,7 @@ function default.grow_new_jungle_tree(pos) local path = minetest.get_modpath("default") .. "/schematics/jungle_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, "0", nil, false) + path, "random", nil, false) end diff --git a/mods/doors/init.lua b/mods/doors/init.lua index dd7ab726..2b129aa2 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -74,17 +74,32 @@ end -- nodes from being placed in the top half of the door. minetest.register_node("doors:hidden", { description = "Hidden Door Segment", - drawtype = "airlike", + -- can't use airlike otherwise falling nodes will turn to entities + -- and will be forever stuck until door is removed. + drawtype = "nodebox", paramtype = "light", + paramtype2 = "facedir", sunlight_propagates = true, - walkable = false, + -- has to be walkable for falling nodes to stop falling. + walkable = true, pointable = false, diggable = false, buildable_to = false, floodable = false, drop = "", - groups = { not_in_creative_inventory = 1 }, - on_blast = function() end + groups = {not_in_creative_inventory = 1}, + on_blast = function() end, + tiles = {"doors_blank.png"}, + -- 1px transparent block inside door hinge near node top. + nodebox = { + type = "fixed", + fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}, + }, + -- collision_box needed otherise selection box would be full node size + collision_box = { + type = "fixed", + fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}, + }, }) -- table used to aid door opening/closing @@ -117,10 +132,19 @@ local transform = { function _doors.door_toggle(pos, clicker) local meta = minetest.get_meta(pos) - local state = meta:get_int("state") local def = minetest.registered_nodes[minetest.get_node(pos).name] local name = def.door.name + local state = meta:get_string("state") + if state == "" then + -- fix up lvm-placed right-hinged doors, default closed + if minetest.get_node(pos).name:sub(-2) == "_b" then + state = 2 + end + else + state = tonumber(state) + end + if clicker and not minetest.check_player_privs(clicker, "protection_bypass") then local owner = meta:get_string("doors_owner") if owner ~= "" then @@ -196,8 +220,21 @@ function doors.register(name, def) -- retain infotext and doors_owner fields minetest.swap_node(pos, {name = name .. "_" .. new.type, param2 = p2}) meta:set_int("state", new.state) + -- properly place doors:hidden at the right spot + local p3 = p2 + if new.state >= 2 then + p3 = (p3 + 3) % 4 + end + if new.state % 2 == 1 then + if new.state >= 2 then + p3 = (p3 + 1) % 4 + else + p3 = (p3 + 3) % 4 + end + end -- wipe meta on top node as it's unused - minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, { name = "doors:hidden" }) + minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, + {name = "doors:hidden", param2 = p3}) end }) @@ -259,10 +296,11 @@ function doors.register(name, def) if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then state = state + 2 minetest.set_node(pos, {name = name .. "_b", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4}) else minetest.set_node(pos, {name = name .. "_a", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = dir}) end - minetest.set_node(above, { name = "doors:hidden" }) local meta = minetest.get_meta(pos) meta:set_int("state", state) @@ -322,7 +360,8 @@ function doors.register(name, def) _doors.door_toggle(pos, clicker) end def.after_dig_node = function(pos, node, meta, digger) - minetest.remove_node({ x = pos.x, y = pos.y + 1, z = pos.z}) + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + nodeupdate({x = pos.x, y = pos.y + 1, z = pos.z}) end def.can_dig = function(pos, player) return can_dig(pos, player) @@ -465,7 +504,7 @@ doors.register("door_glass", { doors.register("door_obsidian_glass", { tiles = { "doors_door_obsidian_glass.png" }, - description = "Glass Door", + description = "Obsidian Glass Door", inventory_image = "doors_item_obsidian_glass.png", groups = { snappy=1, cracky=1, oddly_breakable_by_hand=3 }, sounds = default.node_sound_glass_defaults(), @@ -658,59 +697,101 @@ minetest.register_craft({ ----fence gate---- -local fence = { - description = "Fence Gate", - drawtype = "mesh", - tiles = {"default_wood.png"}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - is_ground_content = false, - drop = "doors:gate_closed", - connect_sides = { "left", "right" }, - groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, - flammable = 2, fence = 1}, - on_rightclick = function(pos, clicker) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - minetest.swap_node(pos, {name = def.gate, param2 = node.param2}) - minetest.sound_play(def.sound, {pos = pos, gain = 0.3, - max_hear_distance = 8}) - end, - selection_box = { +function doors.register_fencegate(name, def) + local fence = { + description = def.description, + drawtype = "mesh", + tiles = { def.texture }, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + is_ground_content = false, + drop = name .. "_closed", + connect_sides = { "left", "right" }, + groups = def.groups, + sounds = def.sounds, + on_rightclick = function(pos, clicker) + local node = minetest.get_node(pos) + local node_def = minetest.registered_nodes[node.name] + minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2}) + minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3, + max_hear_distance = 8}) + end, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/4, 1/2, 1/2, 1/4}, + }, + } + + if not fence.sounds then + fence.sounds = default.node_sound_wood_defaults() + end + + fence.groups.fence = 1 + + local fence_closed = table.copy(fence) + fence_closed.mesh = "doors_fencegate_closed.obj" + fence_closed.gate = name .. "_open" + fence_closed.sound = "doors_fencegate_open" + fence_closed.collision_box = { type = "fixed", fixed = {-1/2, -1/2, -1/4, 1/2, 1/2, 1/4}, - }, -} + } -local fence_closed = table.copy(fence) -fence_closed.mesh = "doors_fencegate_closed.obj" -fence_closed.gate = "doors:gate_open" -fence_closed.sound = "doors_fencegate_open" -fence_closed.collision_box = { - type = "fixed", - fixed = {-1/2, -1/2, -1/4, 1/2, 1/2, 1/4}, -} + local fence_open = table.copy(fence) + fence_open.mesh = "doors_fencegate_open.obj" + fence_open.gate = name .. "_closed" + fence_open.sound = "doors_fencegate_close" + fence_open.groups.not_in_creative_inventory = 1 + fence_open.collision_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/4, -3/8, 1/2, 1/4}, + {-5/8, -3/8, -14/16, -3/8, 3/8, 0}}, + } -local fence_open = table.copy(fence) -fence_open.mesh = "doors_fencegate_open.obj" -fence_open.gate = "doors:gate_closed" -fence_open.sound = "doors_fencegate_close" -fence_open.groups.not_in_creative_inventory = 1 -fence_open.collision_box = { - type = "fixed", - fixed = {{-1/2, -1/2, -1/4, -3/8, 1/2, 1/4}, - {-5/8, -3/8, -14/16, -3/8, 3/8, 0}}, -} + minetest.register_node(":" .. name .. "_closed", fence_closed) + minetest.register_node(":" .. name .. "_open", fence_open) -minetest.register_node("doors:gate_closed", fence_closed) -minetest.register_node("doors:gate_open", fence_open) + minetest.register_craft({ + output = name .. "_closed", + recipe = { + {"default:stick", def.material, "default:stick"}, + {"default:stick", def.material, "default:stick"} + } + }) +end -minetest.register_craft({ - output = "doors:gate_closed", - recipe = { - {"default:stick", "group:wood", "default:stick"}, - {"default:stick", "group:wood", "default:stick"}, - }, +doors.register_fencegate("doors:gate_wood", { + description = "Wooden Fence Gate", + texture = "default_wood.png", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} }) +doors.register_fencegate("doors:gate_acacia_wood", { + description = "Acacia Fence Gate", + texture = "default_acacia_wood.png", + material = "default:acacia_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_junglewood", { + description = "Junglewood Fence Gate", + texture = "default_junglewood.png", + material = "default:junglewood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_pine_wood", { + description = "Pine Fence Gate", + texture = "default_pine_wood.png", + material = "default:pine_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_aspen_wood", { + description = "Aspen Fence Gate", + texture = "default_aspen_wood.png", + material = "default:aspen_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) diff --git a/mods/doors/textures/doors_blank.png b/mods/doors/textures/doors_blank.png new file mode 100644 index 00000000..1914264c Binary files /dev/null and b/mods/doors/textures/doors_blank.png differ diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 1fc942b8..c6f3d479 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -78,15 +78,19 @@ minetest.register_tool("fire:flint_and_steel", { local pt = pointed_thing if pt.type == "node" and minetest.get_node(pt.above).name == "air" then - if not minetest.is_protected(pt.above, player_name) then - minetest.set_node(pt.above, {name="fire:basic_flame"}) - else - minetest.chat_send_player(player_name, "This area is protected") + itemstack:add_wear(1000) + local node_under = minetest.get_node(pt.under).name + + if minetest.get_node_group(node_under, "flammable") >= 1 then + if not minetest.is_protected(pt.above, player_name) then + minetest.set_node(pt.above, {name = "fire:basic_flame"}) + else + minetest.chat_send_player(player_name, "This area is protected") + end end end - + if not minetest.setting_getbool("creative_mode") then - itemstack:add_wear(1000) return itemstack end end @@ -231,7 +235,7 @@ else nodenames = {"group:flammable"}, neighbors = {"group:igniter"}, interval = 7, - chance = 16, + chance = 12, catch_up = false, action = function(p0, node, _, _) -- If there is water or stuff like that around node, don't ignite @@ -250,7 +254,7 @@ else minetest.register_abm({ nodenames = {"fire:basic_flame"}, interval = 5, - chance = 16, + chance = 6, catch_up = false, action = function(p0, node, _, _) -- If there are no flammable nodes around flame, remove flame diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index dd90f4c9..85fa36ef 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -31,7 +31,6 @@ minetest.register_alias("flowers:flower_dandelion_white", "flowers:dandelion_whi local function add_simple_flower(name, desc, box, f_groups) -- Common flowers' groups f_groups.snappy = 3 - f_groups.flammable = 2 f_groups.flower = 1 f_groups.flora = 1 f_groups.attached_node = 1 @@ -134,7 +133,7 @@ minetest.register_node("flowers:mushroom_red", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flammable = 3, attached_node = 1}, + groups = {snappy = 3, attached_node = 1}, sounds = default.node_sound_leaves_defaults(), on_use = minetest.item_eat(-5), selection_box = { @@ -153,7 +152,7 @@ minetest.register_node("flowers:mushroom_brown", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {snappy = 3, flammable = 3, attached_node = 1}, + groups = {snappy = 3, attached_node = 1}, sounds = default.node_sound_leaves_defaults(), on_use = minetest.item_eat(1), selection_box = { diff --git a/mods/screwdriver/init.lua b/mods/screwdriver/init.lua index 6b82d042..5e6df62f 100644 --- a/mods/screwdriver/init.lua +++ b/mods/screwdriver/init.lua @@ -18,10 +18,9 @@ screwdriver.rotate_simple = function(pos, node, user, mode, new_param2) return false end end -local USES = 200 -- Handles rotation -local function screwdriver_handler(itemstack, user, pointed_thing, mode) +screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) if pointed_thing.type ~= "node" then return end @@ -82,7 +81,7 @@ local function screwdriver_handler(itemstack, user, pointed_thing, mode) end if not minetest.setting_getbool("creative_mode") then - itemstack:add_wear(65535 / (USES - 1)) + itemstack:add_wear(65535 / ((uses or 200) - 1)) end return itemstack @@ -93,11 +92,11 @@ minetest.register_tool("screwdriver:screwdriver", { description = "Screwdriver (left-click rotates face, right-click rotates axis)", inventory_image = "screwdriver.png", on_use = function(itemstack, user, pointed_thing) - screwdriver_handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE) + screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE, 200) return itemstack end, on_place = function(itemstack, user, pointed_thing) - screwdriver_handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS) + screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, 200) return itemstack end, })