diff --git a/.gitignore b/.gitignore index 632b4fc..095dd08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.pyc *.kate-swp +/nohup.out diff --git a/etc/game-install-ENLIVEN b/etc/game-install-ENLIVEN index 537cc75..2bf83bb 100755 --- a/etc/game-install-ENLIVEN +++ b/etc/game-install-ENLIVEN @@ -1082,7 +1082,15 @@ fi sudo cp -f $MODIFIED_PATH "$MT_MYGAME_DIR/mods/bones/" echo "done attempting to patch $MTMOD_DEST_PATH/" else - echo "FAILED to patch $MTMOD_DEST_NAME since $TARGET_PATH differs from known version (this is not a problem if you ran the patcher more than once)." + BASIS_PATH=$PATCHES_PATH/subgame-basis/mods/bones/init-0.5.0-dev.lua + TRY_DIFF="`diff $BASIS_PATH $TARGET_PATH`" + if [ -z "$TRY_DIFF" ]; then + sudo cp -f $MODIFIED_PATH "$MT_MYGAME_DIR/mods/bones/init.lua" + echo "patched $MT_MYGAME_DIR/mods/bones/init.lua" + else + TRY_DONE_DIFF="`diff $MODIFIED_PATH $TARGET_PATH`" + echo "ALREADY patched $MTMOD_DEST_NAME." + fi fi BASIS_PATH=$PATCHES_PATH/subgame-basis/mods/homedecor_modpack/homedecor/gastronomy.lua MODIFIED_PATH=$PATCHES_PATH/subgame/mods/homedecor_modpack/homedecor/gastronomy.lua diff --git a/patches/mods-multiplayer/bones_log/init.lua b/patches/mods-multiplayer/bones_log/init.lua new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/patches/mods-multiplayer/bones_log/init.lua @@ -0,0 +1 @@ + diff --git a/patches/subgame-basis/mods/bones/init-0.5.0-dev.lua b/patches/subgame-basis/mods/bones/init-0.5.0-dev.lua new file mode 100644 index 0000000..4294518 --- /dev/null +++ b/patches/subgame-basis/mods/bones/init-0.5.0-dev.lua @@ -0,0 +1,259 @@ +-- Minetest 0.4 mod: bones +-- See README.txt for licensing and other information. + +bones = {} + +local function is_owner(pos, name) + local owner = minetest.get_meta(pos):get_string("owner") + if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then + return true + end + return false +end + +local 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]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + +local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200 +local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 + +minetest.register_node("bones:bones", { + description = "Bones", + tiles = { + "bones_top.png^[transform2", + "bones_bottom.png", + "bones_side.png", + "bones_side.png", + "bones_rear.png", + "bones_front.png" + }, + paramtype2 = "facedir", + groups = {dig_immediate = 2}, + sounds = default.node_sound_gravel_defaults(), + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if meta:get_inventory():is_empty("main") then + local inv = player:get_inventory() + if inv:room_for_item("main", {name = "bones:bones"}) then + inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos, "bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_punch = function(pos, node, player) + if not is_owner(pos, player:get_player_name()) then + return + end + + if minetest.get_meta(pos):get_string("infotext") == "" then + return + end + + local inv = minetest.get_meta(pos):get_inventory() + local player_inv = player:get_inventory() + local has_space = true + + for i = 1, inv:get_size("main") do + local stk = inv:get_stack("main", i) + if player_inv:room_for_item("main", stk) then + inv:set_stack("main", i, nil) + player_inv:add_item("main", stk) + else + has_space = false + break + end + end + + -- remove bones if player emptied them + if has_space then + if player_inv:room_for_item("main", {name = "bones:bones"}) then + player_inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos,"bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_timer = function(pos, elapsed) + local meta = minetest.get_meta(pos) + local time = meta:get_int("time") + elapsed + if time >= share_bones_time then + meta:set_string("infotext", meta:get_string("owner") .. "'s old bones") + meta:set_string("owner", "") + else + meta:set_int("time", time) + return true + end + end, + on_blast = function(pos) + end, +}) + +local function may_replace(pos, player) + local node_name = minetest.get_node(pos).name + local node_definition = minetest.registered_nodes[node_name] + + -- if the node is unknown, we return false + if not node_definition then + return false + end + + -- allow replacing air and liquids + if node_name == "air" or node_definition.liquidtype ~= "none" then + return true + end + + -- don't replace filled chests and other nodes that don't allow it + local can_dig_func = node_definition.can_dig + if can_dig_func and not can_dig_func(pos, player) then + return false + end + + -- default to each nodes buildable_to; if a placed block would replace it, why shouldn't bones? + -- flowers being squished by bones are more realistical than a squished stone, too + -- exception are of course any protected buildable_to + return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) +end + +local drop = function(pos, itemstack) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) + if obj then + obj:setvelocity({ + x = math.random(-10, 10) / 9, + y = 5, + z = math.random(-10, 10) / 9, + }) + end +end + +local player_inventory_lists = { "main", "craft" } +bones.player_inventory_lists = player_inventory_lists + +local function is_all_empty(player_inv) + for _, list_name in ipairs(player_inventory_lists) do + if not player_inv:is_empty(list_name) then + return false + end + end + return true +end + +minetest.register_on_dieplayer(function(player) + + local bones_mode = minetest.settings:get("bones_mode") or "bones" + if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then + bones_mode = "bones" + end + + -- return if keep inventory set or in creative mode + if bones_mode == "keep" or (creative and creative.is_enabled_for + and creative.is_enabled_for(player:get_player_name())) then + return + end + + local player_inv = player:get_inventory() + if is_all_empty(player_inv) then + return + end + + local pos = vector.round(player:getpos()) + local player_name = player:get_player_name() + + -- check if it's possible to place bones, if not find space near player + if bones_mode == "bones" and not may_replace(pos, player) then + local air = minetest.find_node_near(pos, 1, {"air"}) + if air and not minetest.is_protected(air, player_name) then + pos = air + else + bones_mode = "drop" + end + end + + if bones_mode == "drop" then + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + drop(pos, player_inv:get_stack(list_name, i)) + end + player_inv:set_list(list_name, {}) + end + drop(pos, ItemStack("bones:bones")) + return + end + + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(pos, {name = "bones:bones", param2 = param2}) + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 8 * 4) + + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + local stack = player_inv:get_stack(list_name, i) + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else -- no space left + drop(pos, stack) + end + end + player_inv:set_list(list_name, {}) + end + + meta:set_string("formspec", bones_formspec) + meta:set_string("owner", player_name) + + if share_bones_time ~= 0 then + meta:set_string("infotext", player_name .. "'s fresh bones") + + if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then + meta:set_int("time", 0) + else + meta:set_int("time", (share_bones_time - share_bones_time_early)) + end + + minetest.get_node_timer(pos):start(10) + else + meta:set_string("infotext", player_name.."'s bones") + end +end) diff --git a/patches/subgame/mods/bones/init-0.5.0-dev.lua b/patches/subgame/mods/bones/init-0.5.0-dev.lua new file mode 100644 index 0000000..5c4ecca --- /dev/null +++ b/patches/subgame/mods/bones/init-0.5.0-dev.lua @@ -0,0 +1,282 @@ +-- Minetest 0.4 mod: bones +-- See README.txt for licensing and other information. + +bones = {} + +local function is_owner(pos, name) + local owner = minetest.get_meta(pos):get_string("owner") + if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then + return true + end + return false +end + +local 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]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + +local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200 +local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 + +minetest.register_node("bones:bones", { + description = "Bones", + tiles = { + "bones_top.png^[transform2", + "bones_bottom.png", + "bones_side.png", + "bones_side.png", + "bones_rear.png", + "bones_front.png" + }, + paramtype2 = "facedir", + groups = {dig_immediate = 2}, + sounds = default.node_sound_gravel_defaults(), + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if meta:get_inventory():is_empty("main") then + local inv = player:get_inventory() + if inv:room_for_item("main", {name = "bones:bones"}) then + inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos, "bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_punch = function(pos, node, player) + if not is_owner(pos, player:get_player_name()) then + return + end + + if minetest.get_meta(pos):get_string("infotext") == "" then + return + end + + local inv = minetest.get_meta(pos):get_inventory() + local player_inv = player:get_inventory() + local has_space = true + + for i = 1, inv:get_size("main") do + local stk = inv:get_stack("main", i) + if player_inv:room_for_item("main", stk) then + inv:set_stack("main", i, nil) + player_inv:add_item("main", stk) + else + has_space = false + break + end + end + + -- remove bones if player emptied them + if has_space then + if player_inv:room_for_item("main", {name = "bones:bones"}) then + player_inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos,"bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_timer = function(pos, elapsed) + local meta = minetest.get_meta(pos) + local time = meta:get_int("time") + elapsed + if time >= share_bones_time then + meta:set_string("infotext", meta:get_string("owner") .. "'s old bones") + meta:set_string("owner", "") + else + meta:set_int("time", time) + return true + end + end, + on_blast = function(pos) + end, +}) + +local function may_replace(pos, player) + local node_name = minetest.get_node(pos).name + local node_definition = minetest.registered_nodes[node_name] + + -- if the node is unknown, we return false + if not node_definition then + return false + end + + -- allow replacing air and liquids + if node_name == "air" or node_definition.liquidtype ~= "none" then + return true + end + + -- don't replace filled chests and other nodes that don't allow it + local can_dig_func = node_definition.can_dig + if can_dig_func and not can_dig_func(pos, player) then + return false + end + + -- default to each nodes buildable_to; if a placed block would replace it, why shouldn't bones? + -- flowers being squished by bones are more realistical than a squished stone, too + -- exception are of course any protected buildable_to + return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) +end + +local drop = function(pos, itemstack) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) + if obj then + obj:setvelocity({ + x = math.random(-10, 10) / 9, + y = 5, + z = math.random(-10, 10) / 9, + }) + end +end + +local player_inventory_lists = { "main", "craft" } +bones.player_inventory_lists = player_inventory_lists + +local function is_all_empty(player_inv) + for _, list_name in ipairs(player_inventory_lists) do + if not player_inv:is_empty(list_name) then + return false + end + end + return true +end + + +minetest.register_on_dieplayer(function(player) + + local bones_mode = minetest.settings:get("bones_mode") or "bones" + if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then + bones_mode = "bones" + end + + local enable_bones_logging = minetest.settings:get_bool("enable_bones_logging") + local enable_bones_chat_msg = minetest.settings:get_bool("enable_bones_chat_msg") + + local pos = vector.round(player:getpos()) + -- return if keep inventory set or in creative mode + if bones_mode == "keep" or (creative and creative.is_enabled_for + and creative.is_enabled_for(player:get_player_name())) then + if enable_bones_logging then + minetest.log("action", "[bones] " .. player:get_player_name() .. "'s bones do not remain since player has creative -- died at " .. minetest.pos_to_string(vector.round(player:getpos()))) + end + if enable_bones_chat_msg then + minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s bones do not remain since player has creative -- died at " .. minetest.pos_to_string(pos)) + end + return + end + + local player_inv = player:get_inventory() + if is_all_empty(player_inv) then + return + end + + local pos = vector.round(player:getpos()) + local player_name = player:get_player_name() + + -- check if it's possible to place bones, if not find space near player + if bones_mode == "bones" and not may_replace(pos, player) then + local air = minetest.find_node_near(pos, 1, {"air"}) + if air and not minetest.is_protected(air, player_name) then + pos = air + else + bones_mode = "drop" + end + end + + if bones_mode == "drop" then + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + drop(pos, player_inv:get_stack(list_name, i)) + end + player_inv:set_list(list_name, {}) + end + drop(pos, ItemStack("bones:bones")) + + if enable_bones_logging then + minetest.log("action", "[bones] " .. player:get_player_name() .. "'s bones do not remain since cannot place bones here -- died at " .. minetest.pos_to_string(pos)) + end + if enable_bones_chat_msg then + minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s do not remain since cannot place bones here -- died at " .. minetest.pos_to_string(pos)) + end + return + end + + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(pos, {name = "bones:bones", param2 = param2}) + if enable_bones_logging then + minetest.log("action", "[bones] " .. player:get_player_name() .. "'s bones remain where died at " .. minetest.pos_to_string(pos)) + end + if enable_bones_chat_msg then + minetest.chat_send_player(player:get_player_name(), player:get_player_name() .. "'s bones remain where died at " .. minetest.pos_to_string(pos)) + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 8 * 4) + + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + local stack = player_inv:get_stack(list_name, i) + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else -- no space left + drop(pos, stack) + end + end + player_inv:set_list(list_name, {}) + end + + meta:set_string("formspec", bones_formspec) + meta:set_string("owner", player_name) + + if share_bones_time ~= 0 then + meta:set_string("infotext", player_name .. "'s fresh bones") + + if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then + meta:set_int("time", 0) + else + meta:set_int("time", (share_bones_time - share_bones_time_early)) + end + + minetest.get_node_timer(pos):start(10) + else + meta:set_string("infotext", player_name.."'s bones") + end +end)