From d6f9a675a1ccec16f19e3a28052c39972276fe3f Mon Sep 17 00:00:00 2001 From: Sokomine Date: Wed, 10 Jul 2013 22:12:29 +0200 Subject: [PATCH] removed small bug/incompatibility with newer systems; added shared locked furnaces --- README.md | 2 + init.lua | 32 +++- liscence.txt | 2 +- shared_locked_furnace.lua | 323 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+), 2 deletions(-) create mode 100644 shared_locked_furnace.lua diff --git a/README.md b/README.md index 566375e..03f6534 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This Mod for Minetest adds objects that can be locked and shared. It is written so that other objects/mods can easily use the functions provided here. Comes with modified chest, sign and xyz' xdoor2 as sample objects. +New: Furnaces added. For the (unmodified) xdoors2, see http://minetest.net/forum/viewtopic.php?id=2757. Chest and sign take their textures out of default. The textures (lock, key and keychain) have been provided by Addi. Please consult textures/licence.txt. The code of the lock mod has been written by Sokomine. @@ -27,6 +28,7 @@ If you do not want any of the objects chest, sign and/or door, just remove the c dofile(minetest.get_modpath("locks").."/shared_locked_chest.lua"); dofile(minetest.get_modpath("locks").."/shared_locked_sign_wall.lua"); dofile(minetest.get_modpath("locks").."/shared_locked_xdoors2.lua"); +dofile(minetest.get_modpath("locks").."/shared_locked_furnace.lua"); I hope this mod will be helpful. diff --git a/init.lua b/init.lua index 82a1dc4..46a837a 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,34 @@ + +--[[ + Shared locked objects (Mod for MineTest) + Allows to restrict usage of blocks to a certain player or a group of + players. + Copyright (C) 2013 Sokomine + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +--]] + +-- Version 1.1 + +-- Changelog: +-- 10.07.2013 * removed a potential bug (now uses string:gmatch) +-- * added shared locked furnaces + + + locks = {}; minetest.register_privilege("openlocks", { description = "allows to open/use all locked objects", give_to_singleplayer = false}); @@ -290,7 +319,7 @@ function locks:lock_handle_input( pos, formname, fields, player ) end -- of /help -- sanitize player input - if( fields.locks_sent_lock_command:find("[^%a%d%s_\- \/\:]")) then + if( fields.locks_sent_lock_command:gmatch("[^%a%d%s_%- %/%:]")) then minetest.chat_send_player(name, "Input contains unsupported characters. Allowed: a-z, A-Z, 0-9, _, -, :."); return; end @@ -529,5 +558,6 @@ minetest.register_craft({ dofile(minetest.get_modpath("locks").."/shared_locked_chest.lua"); dofile(minetest.get_modpath("locks").."/shared_locked_sign_wall.lua"); dofile(minetest.get_modpath("locks").."/shared_locked_xdoors2.lua"); +dofile(minetest.get_modpath("locks").."/shared_locked_furnace.lua"); diff --git a/liscence.txt b/liscence.txt index 5a2cc67..7dd6dff 100644 --- a/liscence.txt +++ b/liscence.txt @@ -5,7 +5,7 @@ License of locks mod for Minetest-c55 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 +the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/shared_locked_furnace.lua b/shared_locked_furnace.lua new file mode 100644 index 0000000..f633221 --- /dev/null +++ b/shared_locked_furnace.lua @@ -0,0 +1,323 @@ + +-- this is a (slightly!) modified copy of minetest_game/mods/default/nodes.lua, +-- containing only the furnace and adopted slightly for my locks mod + + +function locks.get_furnace_active_formspec(pos, percent) + local formspec = + "size[8,9]".. + "image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:".. + (100-percent)..":default_furnace_fire_fg.png]".. + "list[current_name;fuel;2,3;1,1;]".. + "list[current_name;src;2,1;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,5;8,4;]".. + + "field[0.3,4.5;6,0.7;locks_sent_lock_command;Locked furnace. Type /help for help:;]".. + "button_exit[6.3,4;1.7,0.7;locks_sent_input;Proceed]" ; + return formspec +end + +locks.furnace_inactive_formspec = + "size[8,9]".. + "image[2,2;1,1;default_furnace_fire_bg.png]".. + "list[current_name;fuel;2,3;1,1;]".. + "list[current_name;src;2,1;1,1;]".. + "list[current_name;dst;5,1;2,2;]".. + "list[current_player;main;0,5;8,4;]".. + "field[0.3,4.5;6,0.7;locks_sent_lock_command;Locked furnace. Type /help for help:;]".. + "button_exit[6.3,4;1.7,0.7;locks_sent_input;Proceed]" ; + +minetest.register_node("locks:shared_locked_furnace", { + description = "Shared locked furnace", + tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", + "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front.png"}, + paramtype2 = "facedir", + groups = {cracky=2}, + legacy_facedir_simple = true, +-- sounds = default.node_sound_stone_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + locks:lock_init( pos, locks.furnace_inactive_formspec) + meta:set_string("infotext", "Shared locked furnace") + local inv = meta:get_inventory() + inv:set_size("fuel", 1) + inv:set_size("src", 1) + inv:set_size("dst", 4) + end, + after_place_node = function(pos, placer) + locks:lock_set_owner( pos, placer, "Shared locked chest" ); + end, + can_dig = function(pos,player) + if( not(locks:lock_allow_dig( pos, player ))) then + return false; + end + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("fuel") then + return false + elseif not inv:is_empty("dst") then + return false + elseif not inv:is_empty("src") then + return false + end + return true + end, + on_receive_fields = function(pos, formname, fields, sender) + locks:lock_handle_input( pos, formname, fields, sender ); + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if( not( locks:lock_allow_use( pos, player ))) 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","Furnace is empty") + end + return stack:get_count() + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if( not( locks:lock_allow_use( pos, player ))) then + return 0; + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + if to_list == "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","Furnace is empty") + end + return count + else + return 0 + end + elseif to_list == "src" then + return count + elseif to_list == "dst" then + return 0 + end + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if( not( locks:lock_allow_use( pos, player ))) then + return 0; + end + return stack:get_count() + end, +}) + +minetest.register_node("locks:shared_locked_furnace_active", { + description = "Furnace", + tiles = {"default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", + "default_furnace_side.png", "default_furnace_side.png", "default_furnace_front_active.png"}, + paramtype2 = "facedir", + light_source = 8, + drop = "locks:shared_locked_furnace", + groups = {cracky=2, not_in_creative_inventory=1}, + legacy_facedir_simple = true, +-- sounds = default.node_sound_stone_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + locks:lock_init( pos, locks.furnace_inactive_formspec) + meta:set_string("infotext", "Shared locked furnace"); + local inv = meta:get_inventory() + inv:set_size("fuel", 1) + inv:set_size("src", 1) + inv:set_size("dst", 4) + end, + can_dig = function(pos,player) + if( not(locks:lock_allow_dig( pos, player ))) then + return false; + end + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + if not inv:is_empty("fuel") then + return false + elseif not inv:is_empty("dst") then + return false + elseif not inv:is_empty("src") then + return false + end + return true + end, + on_receive_fields = function(pos, formname, fields, sender) + locks:lock_handle_input( pos, formname, fields, sender ); + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if( not( locks:lock_allow_use( pos, player ))) 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","Shared locked furnace (empty)") + end + return stack:get_count() + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if( not( locks:lock_allow_use( pos, player ))) then + return 0; + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + if to_list == "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","Shared locked furnace (empty)") + end + return count + else + return 0 + end + elseif to_list == "src" then + return count + elseif to_list == "dst" then + return 0 + end + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if( not( locks:lock_allow_use( pos, player ))) then + return 0; + end + return stack:get_count() + end, +}) + +-- better make this a function specific to this mod to avoid trouble with the same function in default +locks.hacky_swap_node = function(pos,name) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local meta0 = meta:to_table() + if node.name == name then + return + end + node.name = name + local meta0 = meta:to_table() + minetest.set_node(pos,node) + meta = minetest.get_meta(pos) + meta:from_table(meta0) +end + +minetest.register_abm({ + nodenames = {"locks:shared_locked_furnace","locks:shared_locked_furnace_active"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local meta = minetest.get_meta(pos) + for i, name in ipairs({ + "fuel_totaltime", + "fuel_time", + "src_totaltime", + "src_time" + }) do + if meta:get_string(name) == "" then + meta:set_float(name, 0.0) + end + end + + local inv = meta:get_inventory() + + local srclist = inv:get_list("src") + local cooked = nil + local aftercooked + + if srclist then + cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + end + + local was_active = false + + if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then + was_active = true + meta:set_float("fuel_time", meta:get_float("fuel_time") + 1) + meta:set_float("src_time", meta:get_float("src_time") + 1) + if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then + -- check if there's room for output in "dst" list + if inv:room_for_item("dst",cooked.item) then + -- Put result in "dst" list + inv:add_item("dst", cooked.item) + -- take stuff from "src" list + inv:set_stack("src", 1, aftercooked.items[1]) + else + print("Could not insert '"..cooked.item:to_string().."'") + end + meta:set_string("src_time", 0) + end + end + + if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then + local percent = math.floor(meta:get_float("fuel_time") / + meta:get_float("fuel_totaltime") * 100) + meta:set_string("infotext","Shared locked furnace active: "..percent.."%") + locks.hacky_swap_node(pos,"locks:shared_locked_furnace_active") + meta:set_string("formspec",locks.get_furnace_active_formspec(pos, percent)) + return + end + + local fuel = nil + local afterfuel + local cooked = nil + local fuellist = inv:get_list("fuel") + local srclist = inv:get_list("src") + + if srclist then + cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + end + if fuellist then + fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + end + + if not( fuel) or fuel.time <= 0 then + meta:set_string("infotext","Shared locked furnace out of fuel") + locks.hacky_swap_node(pos,"locks:shared_locked_furnace") + meta:set_string("formspec", locks.furnace_inactive_formspec) + return + end + + if cooked.item:is_empty() then + if was_active then + meta:set_string("infotext","Shared locked furnace is empty") + locks.hacky_swap_node(pos,"locks:shared_locked_furnace") + meta:set_string("formspec", locks.furnace_inactive_formspec) + end + return + end + + meta:set_string("fuel_totaltime", fuel.time) + meta:set_string("fuel_time", 0) + + inv:set_stack("fuel", 1, afterfuel.items[1]) + end, +}) + + +minetest.register_craft({ + output = 'locks:shared_locked_furnace', + recipe = { + { 'default:furnace', 'locks:lock', '' }, + }, +}) + +print( "[Mod] locks: loading locks:shared_locked_furnace");