diff --git a/chatcommands.lua b/chatcommands.lua new file mode 100644 index 0000000..7543e5b --- /dev/null +++ b/chatcommands.lua @@ -0,0 +1,274 @@ +local colors = { + ["yellow"] = "#FFEB3B", -- info + ["green"] = "#4CAF50", -- success + ["red"] = "#f44336", -- error + ["cyan"] = "#00BCD4" -- terminal info +} + +minetest.override_chatcommand("home", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + local player_pos = player:get_pos() + + if not player then + return false, minetest.colorize(colors.red, "Player not found.") + end + + if minetest.global_exists("pvp_block") then + if pvp_block:in_area(player_pos) then + return false, minetest.colorize(colors.red, "You cannot do this in PvP arena.") + end + end + + if minetest.global_exists("sethome") then + if sethome.go(name) then + return true, minetest.colorize(colors.green, "Teleported to home!") + end + return false, minetest.colorize(colors.yellow, "Set a home using /sethome") + end + + return false, minetest.colorize(colors.yellow, "Something went wrong, try again.") + end +}) + +-- Spawn mod for Minetest +-- Originally written by VanessaE (I think), rewritten by cheapie +-- WTFPL + +local spawn_spawnpos = minetest.setting_get_pos("static_spawnpoint") + +minetest.register_chatcommand("spawn", { + params = "", + description = "Teleport to the spawn point.", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local player_pos = player:get_pos() + + if not player then + return false, minetest.colorize(colors.red, "Player not found.") + end + + if minetest.global_exists("pvp_block") then + if pvp_block:in_area(player_pos) then + return false, minetest.colorize(colors.red, "You cannot do this in PvP arena.") + end + end + + if spawn_spawnpos then + -- prevent teleporting to spawn when already at spawn, or in jail at spawn + if vector.distance(player_pos, spawn_spawnpos) < 48 then + return false, minetest.colorize(colors.yellow, "You are already near the spawn, teleporting aborted.") + end + + player:set_pos(spawn_spawnpos) + return true, minetest.colorize(colors.green, "Teleporting to spawn..") + else + return false, minetest.colorize(colors.yellow, "The spawn point is not set!") + end + end, +}) + +minetest.register_chatcommand("setspawn", { + params = "", + description = "Sets the spawn point to your current position", + privs = {server = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + + if not player then + return false, minetest.colorize(colors.red, "Player not found") + end + + local pos = player:get_pos() + local x = pos.x + local y = pos.y + 1 + local z = pos.z + local pos_string = x..","..y..","..z + local pos_string_2 = "Setting spawn point to ("..x..", "..y..", "..z..")" + + minetest.settings:set("static_spawnpoint", pos_string) + spawn_spawnpos = pos + + if minetest.settings:write() then + return true, minetest.colorize(colors.yellow, pos_string_2) + else + return false, minetest.colorize(colors.red, "Something went wrong, the new spawn position was not saved in minetest.conf file.") + end + end, +}) + +-- Original code by Traxie21 and released with the WTFPL license +-- https://forum.minetest.net/viewtopic.php?id=4457 +-- Updates by Zeno, ChaosWormz, SaKeL + +local timeout_delay = 5 +local version = "1.1" +local tpr_list = {} +local tphr_list = {} + +-- Copied from Celeron-55"s /teleport command. Thanks Celeron! +local function find_free_position_near(pos) + local tries = { + { x = 1, y = 0, z = 0 }, + { x = -1, y = 0, z = 0 }, + { x = 0, y = 0, z = 1 }, + { x = 0, y = 0, z = -1 }, + } + + for _, d in ipairs(tries) do + local p = { x = pos.x + d.x, y = pos.y + d.y, z = pos.z + d.z } + local n = minetest.get_node(p) + + if not minetest.registered_nodes[n.name].walkable then + return p, true + end + end + + return pos, false +end + +minetest.register_chatcommand("tpr", { + description = "Request teleport to another player.", + params = " | leave playername empty to see help message", + privs = { interact = true }, + func = function(name, param) + local receiver = param + + if receiver == "" then + return false, minetest.colorize(colors.yellow, "Usage: /tpr ") + end + + local player = minetest.get_player_by_name(name) + local player_pos = player:get_pos() + + if minetest.global_exists("pvp_block") then + if pvp_block:in_area(player_pos) then + return false, minetest.colorize(colors.red, "You cannot do this in PvP arena.") + end + end + + -- If paremeter is valid, Send teleport message and set the table. + if minetest.get_player_by_name(receiver) then + minetest.chat_send_player(receiver, minetest.colorize(colors.yellow, name .." is requesting to teleport to you. /tpy to accept.")) + + -- Write name values to list and clear old values. + tpr_list[receiver] = name + + -- Teleport timeout delay + minetest.after(timeout_delay, function(name, receiver) + if tpr_list[name] ~= nil then + tpr_list[name] = nil + end + + if name and receiver then + minetest.chat_send_player(name, minetest.colorize(colors.yellow, "Teleport request to "..receiver.." timed out.")) + minetest.chat_send_player(receiver, minetest.colorize(colors.yellow, "Teleport request from "..name.." timed out.")) + end + end, name, receiver) + + return true, minetest.colorize(colors.green, "Teleport request sent! It will time out in ".. timeout_delay .." seconds.") + end + + return false, minetest.colorize(colors.red, "Player not found.") + end +}) + +minetest.register_chatcommand("tphr", { + description = "Request player to teleport to you.", + params = " | leave playername empty to see help message", + privs = { interact = true }, + func = function(name, param) + local receiver = param + + if receiver == "" then + return false, minetest.colorize(colors.red, "Usage: /tphr ") + end + + -- If paremeter is valid, Send teleport message and set the table. + if minetest.get_player_by_name(receiver) then + minetest.chat_send_player(receiver, minetest.colorize(colors.yellow, name .." is requesting that you teleport to them. /tpy to accept; /tpn to deny")) + + -- Write name values to list and clear old values. + tphr_list[receiver] = name + + -- Teleport timeout delay + minetest.after(timeout_delay, function(name) + if tphr_list[name] ~= nil then + tphr_list[name] = nil + end + + if name and receiver then + minetest.chat_send_player(name, minetest.colorize(colors.yellow, "Teleport request to "..receiver.." timed out.")) + minetest.chat_send_player(receiver, minetest.colorize(colors.yellow, "Teleport request from "..name.." timed out.")) + end + end, name, receiver) + + return true, minetest.colorize(colors.green, "Teleport request sent! It will time out in ".. timeout_delay .." seconds.") + end + + return false, minetest.colorize(colors.red, "Player not found.") + end, +}) + +minetest.register_chatcommand("tpy", { + description = "Accept teleport requests from another player", + func = function(name, param) + -- Check to prevent constant teleporting. + if tpr_list[name] == nil and tphr_list[name] == nil then + return false, minetest.colorize(colors.green, "Usage: /tpy allows you to accept teleport requests sent to you by other players") + end + + local chatmsg + local source = nil + local target = nil + local name2 + + if tpr_list[name] then + name2 = tpr_list[name] + source = minetest.get_player_by_name(name) + target = minetest.get_player_by_name(name2) + chatmsg = name2 .. " is teleporting to you." + tpr_list[name] = nil + + elseif tphr_list[name] then + name2 = tphr_list[name] + source = minetest.get_player_by_name(name2) + target = minetest.get_player_by_name(name) + chatmsg = "You are teleporting to " .. name2 .. "." + tphr_list[name] = nil + + else + return false + end + + -- Could happen if either player disconnects (or timeout); if so just abort + if source == nil or target == nil then + return false, minetest.colorize(colors.red, "Player not found.") + end + + minetest.chat_send_player(name2, minetest.colorize(colors.green, "Request Accepted!")) + + local p = source:getpos() + local p = find_free_position_near(p) + target:setpos(p) + + return true, minetest.colorize(colors.green, chatmsg) + end, +}) + +minetest.register_chatcommand("tpn", { + description = "Deny teleport requests from another player.", + func = function(name, param) + if tpr_list[name] ~= nil then + tpr_list[name] = nil + return true, minetest.colorize(colors.red, "Teleport request denied.") + end + + if tphr_list[name] ~= nil then + tphr_list[name] = nil + return true, minetest.colorize(colors.red, "Teleport request denied.") + end + + return false + end, +}) diff --git a/chests.lua b/chests.lua new file mode 100644 index 0000000..141ff08 --- /dev/null +++ b/chests.lua @@ -0,0 +1,187 @@ +-- +-- Mystery Chest +-- +local open_chests = {} + +function get_chest_formspec(pos) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local formspec = + "size[8,9]".. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[nodemeta:" .. spos .. ";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[nodemeta:" .. spos .. ";main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + return formspec +end + +local function chest_lid_obstructed(pos) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local def = minetest.registered_nodes[minetest.get_node(above).name] + -- allow ladders, signs, wallmounted things and torches to not obstruct + if def and + (def.drawtype == "airlike" or + def.drawtype == "signlike" or + def.drawtype == "torchlike" or + (def.drawtype == "nodebox" and def.paramtype2 == "wallmounted")) then + return false + end + return true +end + +function chest_lid_close(pn) + local chest_open_info = open_chests[pn] + local pos = chest_open_info.pos + local sound = chest_open_info.sound + local swap = chest_open_info.swap + + open_chests[pn] = nil + for k, v in pairs(open_chests) do + if v.pos.x == pos.x and v.pos.y == pos.y and v.pos.z == pos.z then + return true + end + end + + local node = minetest.get_node(pos) + minetest.after(0.2, minetest.swap_node, pos, { name = "x_default:" .. swap, + param2 = node.param2 }) + minetest.sound_play(sound, {gain = 0.3, pos = pos, max_hear_distance = 10}) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "x_default:mystery_chest" then + return + end + if not player or not fields.quit then + return + end + local pn = player:get_player_name() + + if not open_chests[pn] then + return + end + + chest_lid_close(pn) + return true +end) + +minetest.register_on_leaveplayer(function(player) + local pn = player:get_player_name() + if open_chests[pn] then + chest_lid_close(pn) + end +end) + +function register_chest(name, d) + local def = table.copy(d) + def.drawtype = "mesh" + def.visual = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.legacy_facedir_simple = true + def.is_ground_content = false + + def.on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Mystery Chest") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end + + def.can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end + + def.on_rightclick = function(pos, node, clicker) + minetest.sound_play(def.sound_open, {gain = 0.3, pos = pos, + max_hear_distance = 10}) + if not chest_lid_obstructed(pos) then + minetest.swap_node(pos, { + name = "x_default:" .. name .. "_open", + param2 = node.param2 }) + end + minetest.after(0.2, minetest.show_formspec, + clicker:get_player_name(), + "x_default:mystery_chest", get_chest_formspec(pos)) + open_chests[clicker:get_player_name()] = { pos = pos, + sound = def.sound_close, swap = name } + end + + def.on_blast = function() end + + def.on_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in mystery chest at " .. minetest.pos_to_string(pos)) + end + + def.on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves " .. stack:get_name() .. + " to mystery chest at " .. minetest.pos_to_string(pos)) + end + + def.on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes " .. stack:get_name() .. + " from mystery chest at " .. minetest.pos_to_string(pos)) + end + + local def_opened = table.copy(def) + local def_closed = table.copy(def) + + def_opened.mesh = "chest_open.obj" + + for i = 1, #def_opened.tiles do + if type(def_opened.tiles[i]) == "string" then + def_opened.tiles[i] = {name = def_opened.tiles[i], backface_culling = true} + elseif def_opened.tiles[i].backface_culling == nil then + def_opened.tiles[i].backface_culling = true + end + end + + def_opened.drop = "x_default:" .. name + def_opened.groups.not_in_creative_inventory = 1 + def_opened.selection_box = { + type = "fixed", + fixed = { -1/2, -1/2, -1/2, 1/2, 3/16, 1/2 }, + } + + def_opened.can_dig = function() + return false + end + + def_opened.on_blast = function() end + + def_closed.mesh = nil + def_closed.drawtype = nil + def_closed.tiles[6] = def.tiles[5] -- swap textures around for "normal" + def_closed.tiles[5] = def.tiles[3] -- drawtype to make them match the mesh + def_closed.tiles[3] = def.tiles[3].."^[transformFX" + + minetest.register_node("x_default:" .. name, def_closed) + minetest.register_node("x_default:" .. name .. "_open", def_opened) +end + +register_chest("mystery_chest", { + description = "Mystery Chest", + tiles = { + "x_default_mystery_chest_top.png", + "x_default_mystery_chest_top.png", + "x_default_mystery_chest_side.png", + "x_default_mystery_chest_side.png", + "x_default_mystery_chest_front.png", + "x_default_mystery_chest_inside.png" + }, + sounds = default.node_sound_stone_defaults(), + sound_open = "x_default_mystery_chest_open", + sound_close = "x_default_mystery_chest_close", + groups = {cracky = 1, level = 2}, + light_source = 6, +}) diff --git a/clean_unknown.lua b/clean_unknown.lua new file mode 100644 index 0000000..9003f8a --- /dev/null +++ b/clean_unknown.lua @@ -0,0 +1,227 @@ +-- +-- define unknown nodes +-- + +-- workbench advanced [DOM] +-- plantlife_modpack: +-- - flowers_plus +-- - along_shore +-- - bushes +-- - trunks +-- - cavestuff +-- - dryplants +-- - ferns +-- - molehills +-- - youngtrees + +local old_nodes = { + "workbench:D", + "flowers:waterlily_s1", + "flowers:waterlily_s2", + "flowers:waterlily_s3", + "flowers:waterlily_s4", + "flowers:seaweed", + "flowers:seaweed_2", + "flowers:seaweed_3", + "flowers:seaweed_4", + "flowers:waterlily_225", + "flowers:waterlily_45", + "flowers:waterlily_675", + "flowers:sunflower", + "flowers:cotton_plant", + "flowers:flower_cotton", + "flowers:flower_cotton_pot", + "flowers:potted_dandelion_white", + "flowers:potted_cotton_plant", + "flowers:cotton", + "flowers:cotton_wad", + "sunflower:sunflower", + "bushes:youngtree2_bottom", + "bushes:bushbranches", + "bushes:bushbranches1", + "bushes:bushbranches2", + "bushes:bushbranches3", + "bushes:bushbranches4", + "bushes:BushLeaves", + "bushes:BushLeaves1", + "bushes:BushLeaves2", + "trunks:twig", + "trunks:twig_1", + "trunks:twig_2", + "trunks:twig_3", + "trunks:twig_4", + "trunks:twig_5", + "trunks:twig_6", + "trunks:twig_7", + "trunks:twig_8", + "trunks:twig_9", + "trunks:twig_10", + "trunks:twig_11", + "trunks:twig_12", + "trunks:twig_13", + "trunks:twigs", + "trunks:twigs_slab", + "trunks:twigs_roof", + "trunks:twigs_roof_corner", + "trunks:twigs_roof_corner_2", + "trunks:moss_fungus", + "trunks:moss", + "trunks:treeroot", + "trunks:jungletreeroot", + "trunks:pine_treeroot", + "trunks:tree_coniferroot", + "trunks:tree_mangroveroot", + "trunks:tree_palmroot", + "trunks:apple_tree_trunkroot", + "trunks:beech_trunkroot", + "trunks:birch_trunkroot", + "trunks:fir_trunkroot", + "trunks:oak_trunkroot", + "trunks:palm_trunkroot", + "trunks:rubber_tree_trunkroot", + "trunks:rubber_tree_trunk_emptyroot", + "trunks:sequoia_trunkroot", + "trunks:spruce_trunkroot", + "trunks:willow_trunkroot", + "cavestuff:pebble_1", + "cavestuff:pebble_2", + "cavestuff:desert_pebble_1", + "cavestuff:desert_pebble_2", + "cavestuff:stalactite_1", + "cavestuff:stalactite_2", + "cavestuff:stalactite_3", + "dryplants:grass_short", + "dryplants:grass", + "dryplants:sickle", + "dryplants:hay", + "dryplants:wetreed", + "dryplants:reedmace_sapling", + "dryplants:reedmace_top", + "dryplants:reedmace", + "dryplants:reedmace_bottom", + "dryplants:reed", + "dryplants:reed_slab", + "dryplants:wetreed_slab", + "dryplants:reed_roof", + "dryplants:wetreed_roof", + "dryplants:reed_roof_corner", + "dryplants:wetreed_roof_corner", + "dryplants:reed_roof_corner_2", + "dryplants:wetreed_roof_corner_2", + "dryplants:juncus", + "dryplants:juncus_02", + "dryplants:reedmace_height_2", + "dryplants:reedmace_height_3_spikes", + "dryplants:reedmace_height_3", + "dryplants:reedmace_water_entity", + "dryplants:reedmace_spikes", + "dryplants:reedmace_water", + "ferns:fiddlehead", + "ferns:ferntuber", + "ferns:tree_fern_leaves", + "ferns:tree_fern_leaves_02", + "ferns:sapling_tree_fern", + "ferns:fiddlehead_roasted", + "ferns:ferntuber_roasted", + "ferns:fern_01", + "ferns:fern_02", + "ferns:fern_03", + "ferns:fern_04", + "ferns:sapling_giant_tree_fern", + "ferns:fern_trunk_big", + "ferns:fern_trunk_big_top", + "ferns:tree_fern_leaves_giant", + "ferns:tree_fern_leave_big", + "ferns:tree_fern_leave_big_end", + "ferns:horsetail_01", + "ferns:horsetail_02", + "ferns:horsetail_03", + "ferns:horsetail_04", + "ferns:fern_trunk", + "molehills:molehill", + "youngtrees:bamboo", + "youngtrees:youngtree2_middle", + "youngtrees:youngtree_top", + "youngtrees:youngtree_middle", + "youngtrees:youngtree_bottom" +} + +-- spacial case (replace with {"default:dirt_with_grass"}) + +-- plantlife_modpack: +-- - woodsoils + +local old_nodes2 = { + "woodsoils:dirt_with_leaves_1", + "woodsoils:dirt_with_leaves_2", + "woodsoils:grass_with_leaves_1", + "woodsoils:grass_with_leaves_2", + "woodsoils:grass_with_leaves_2" +} + +-- +-- define unknown entities +-- + +local old_entities = {} + +-- +-- assign a flag to nodes what should be removed +-- + +for _,node_name in ipairs(old_nodes) do + minetest.register_node(":"..node_name, { + groups = {old=1}, + }) +end + +for _,node_name2 in ipairs(old_nodes2) do + minetest.register_node(":"..node_name2, { + groups = {old2=1}, + }) +end + +-- +-- remove unknown nodes +-- + +-- remove node {"air"} +if #old_nodes > 0 then + minetest.register_lbm({ + name="enhancements:clean_unknown_to_air", + nodenames = {"group:old"}, + run_at_every_load = true, + action = function(pos, node) + minetest.remove_node(pos) + minetest.log("action", "[Mod][clean_unknown] Cleaning node "..node.name.." at position "..minetest.pos_to_string(pos)) + end, + }) +end + +-- set node {"default:dirt_with_grass"} +if #old_nodes2 > 0 then + minetest.register_lbm({ + name="enhancements:clean_unknown_to_dirt", + nodenames = {"group:old2"}, + run_at_every_load = true, + action = function(pos, node) + minetest.set_node(pos, {name="default:dirt_with_grass"}) + minetest.log("action", "[Mod][clean_unknown] Cleaning node "..node.name.." at position "..minetest.pos_to_string(pos)) + end, + }) +end + +-- +-- remove unknown entities +-- + +if #old_entities > 0 then + for _,entity_name in ipairs(old_entities) do + minetest.register_entity(":"..entity_name, { + on_activate = function(self, staticdata) + self.object:remove() + minetest.log("action", "[Mod][clean_unknown] Cleaning entity "..entity_name) + end, + }) + end +end diff --git a/crafting.lua b/crafting.lua index 448f95d..a9db856 100644 --- a/crafting.lua +++ b/crafting.lua @@ -102,4 +102,10 @@ minetest.register_craft({ {"x_default:lapis_gold_block", "default:obsidian"}, {"default:obsidian", "x_default:lapis_gold_block"}, } -}) \ No newline at end of file +}) + +minetest.register_craft({ + type = "shapeless", + output = "default:bronze_ingot", + recipe = {"default:steel_ingot", "default:copper_ingot"}, +}) diff --git a/depends.txt b/depends.txt index 331d858..4ad96d5 100644 --- a/depends.txt +++ b/depends.txt @@ -1 +1 @@ -default \ No newline at end of file +default diff --git a/functions.lua b/functions.lua index e63c05a..b353e11 100644 --- a/functions.lua +++ b/functions.lua @@ -75,4 +75,49 @@ minetest.register_on_dieplayer(function(player, reason) player_inv:set_list(list_name, {}) end end -end) \ No newline at end of file +end) + +-- External Command (external_cmd) mod by Menche +-- Allows server commands / chat from outside minetest +-- License: LGPL + +local external_cmd_admin = "SERVER" +local external_cmd_timer = 0 +-- local external_cmd_admin = minetest.settings:get("name") + +-- if external_cmd_admin == nil then +-- external_cmd_admin = "SERVER" +-- end + +minetest.register_globalstep(function(dtime) + external_cmd_timer = external_cmd_timer + dtime + + -- every 5 second + if external_cmd_timer >= 5 then + external_cmd_timer = 0 + local f = (io.open(minetest.get_worldpath().."/message", "r")) + + if f ~= nil then + local message = f:read("*line") + f:close() + os.remove(minetest.get_worldpath().."/message") + + if message ~= nil then + local cmd, param = string.match(message, "^/([^ ]+) *(.*)") + + if not param then + param = "" + end + + local cmd_def = minetest.registered_chatcommands[cmd] + + if cmd_def then + cmd_def.func(external_cmd_admin, param) + else + minetest.chat_send_all(external_cmd_admin..": "..message) + end + end + end + + end +end) diff --git a/init.lua b/init.lua index c5a64e5..b54fb20 100644 --- a/init.lua +++ b/init.lua @@ -11,6 +11,11 @@ local default_path = minetest.get_modpath("x_default") dofile(default_path.."/mapgen.lua") dofile(default_path.."/functions.lua") dofile(default_path.."/nodes.lua") +dofile(default_path.."/chests.lua") +dofile(default_path.."/tools.lua") dofile(default_path.."/pvp.lua") +dofile(default_path.."/item_drop.lua") +-- dofile(default_path.."/clean_unknown.lua") dofile(default_path.."/craftitems.lua") dofile(default_path.."/crafting.lua") +dofile(default_path.."/chatcommands.lua") diff --git a/item_drop.lua b/item_drop.lua new file mode 100644 index 0000000..a7ed97f --- /dev/null +++ b/item_drop.lua @@ -0,0 +1,168 @@ +--basic settings +item_drop_settings = {} --settings table +item_drop_settings.radius_magnet = 2.5 --radius of item magnet +item_drop_settings.radius_collect = 0.4 --radius of collection +item_drop_settings.player_collect_height = 1.5 --added to their pos y value +local item_drop_delay = 0 +local item_drop_timer = 0 +local hide_nametag_timer = 0 + +local sneak = {} + +minetest.register_on_joinplayer(function(player) + local player_name = player:get_player_name() + sneak[player_name] = false +end) + +minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + sneak[player_name] = nil +end) + +minetest.register_globalstep(function(dtime) + item_drop_timer = item_drop_timer + dtime + hide_nametag_timer = hide_nametag_timer + dtime + + -- autopickup items when sneaking + if item_drop_timer >= 0.2 then + for _, player in ipairs(minetest.get_connected_players()) do + local control = player:get_player_control() + local player_hp = player:get_hp() + local player_name = player:get_player_name() + + if control.sneak and (player_hp > 0 or not minetest.settings:get_bool("enable_damage")) then + + -- [Shift + E + Q] single drop item + -- autopickup after item_drop_delay + if control.aux1 then + item_drop_delay = 3 + end + + if item_drop_delay > 0 then + minetest.after(item_drop_delay, function() + item_drop_delay = 0 + end) + return + else + pick_dropped_items(player) + end + + end + end + + item_drop_timer = 0 + end + + -- hide nametag and mute footsteps when sneaking + if hide_nametag_timer >= 1 then + for _, player in ipairs(minetest.get_connected_players()) do + local control = player:get_player_control() + local player_hp = player:get_hp() + local player_name = player:get_player_name() + + -- hide nametag when sneaking + if control.sneak ~= sneak[player_name] then + if control.sneak and player_hp > 0 then + local nametag_tbl = player:get_nametag_attributes() + nametag_tbl.color.a = 0 + player:set_nametag_attributes(nametag_tbl) + player:set_properties{makes_footstep_sound = false} + else + local nametag_tbl = player:get_nametag_attributes() + nametag_tbl.color.a = 255 + player:set_nametag_attributes(nametag_tbl) + player:set_properties{makes_footstep_sound = true} + end + sneak[player_name] = control.sneak + end + end + + hide_nametag_timer = 0 + end +end) + +function pick_dropped_items(player) + local pos = player:getpos() + local inv = player:get_inventory() + + --collection + for _,object in ipairs(minetest.get_objects_inside_radius({x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}, item_drop_settings.radius_collect)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) + if object:get_luaentity().itemstring ~= "" then + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 16, + gain = 0.4, + }) + end + object:get_luaentity().itemstring = "" + object:remove() + end + end + end + + --magnet + for _,object in ipairs(minetest.get_objects_inside_radius({x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}, item_drop_settings.radius_magnet)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + + object:get_luaentity().collect = true + + if object:get_luaentity().collect then + if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + + local pos1 = pos + pos1.y = pos1.y+0.2 + local pos2 = object:getpos() + local vec = {x=pos1.x-pos2.x, y=(pos1.y+item_drop_settings.player_collect_height)-pos2.y, z=pos1.z-pos2.z} + + vec.x = pos2.x + vec.x + vec.y = pos2.y + vec.y + vec.z = pos2.z + vec.z + object:moveto(vec) + + object:get_luaentity().physical_state = false + object:get_luaentity().object:set_properties({ + physical = false + }) + + object:setacceleration({x=0, y=0, z=0}) + object:setvelocity({x=0, y=0, z=0}) + + --fix eternally falling items + minetest.after(0, function() + object:setacceleration({x=0, y=0, z=0}) + object:setvelocity({x=0, y=0, z=0}) + end) + + minetest.after(1, function(args) + local lua = object:get_luaentity() + if object == nil or lua == nil or lua.itemstring == nil then + return + end + if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) + if object:get_luaentity().itemstring ~= "" then + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 100, + gain = 0.4, + }) + end + object:get_luaentity().itemstring = "" + object:remove() + else + object:setvelocity({x=0,y=0,z=0}) + object:get_luaentity().physical_state = true + object:get_luaentity().object:set_properties({ + physical = true + }) + end + end, {player, object}) + + end + end + end + end +end diff --git a/sounds/x_default_mystery_chest_close.1.ogg b/sounds/x_default_mystery_chest_close.1.ogg new file mode 100644 index 0000000..a777e4d Binary files /dev/null and b/sounds/x_default_mystery_chest_close.1.ogg differ diff --git a/sounds/x_default_mystery_chest_close.2.ogg b/sounds/x_default_mystery_chest_close.2.ogg new file mode 100644 index 0000000..ac24db7 Binary files /dev/null and b/sounds/x_default_mystery_chest_close.2.ogg differ diff --git a/sounds/x_default_mystery_chest_open.1.ogg b/sounds/x_default_mystery_chest_open.1.ogg new file mode 100644 index 0000000..304f2ce Binary files /dev/null and b/sounds/x_default_mystery_chest_open.1.ogg differ diff --git a/sounds/x_default_mystery_chest_open.2.ogg b/sounds/x_default_mystery_chest_open.2.ogg new file mode 100644 index 0000000..da1a49e Binary files /dev/null and b/sounds/x_default_mystery_chest_open.2.ogg differ diff --git a/textures/x_default_mystery_chest_front.png b/textures/x_default_mystery_chest_front.png new file mode 100644 index 0000000..7a56fc4 Binary files /dev/null and b/textures/x_default_mystery_chest_front.png differ diff --git a/textures/x_default_mystery_chest_inside.png b/textures/x_default_mystery_chest_inside.png new file mode 100644 index 0000000..6282576 Binary files /dev/null and b/textures/x_default_mystery_chest_inside.png differ diff --git a/textures/x_default_mystery_chest_lock.png b/textures/x_default_mystery_chest_lock.png new file mode 100644 index 0000000..73f46c7 Binary files /dev/null and b/textures/x_default_mystery_chest_lock.png differ diff --git a/textures/x_default_mystery_chest_side.png b/textures/x_default_mystery_chest_side.png new file mode 100644 index 0000000..76bd2aa Binary files /dev/null and b/textures/x_default_mystery_chest_side.png differ diff --git a/textures/x_default_mystery_chest_top.png b/textures/x_default_mystery_chest_top.png new file mode 100644 index 0000000..fd91bc2 Binary files /dev/null and b/textures/x_default_mystery_chest_top.png differ diff --git a/tools.lua b/tools.lua new file mode 100644 index 0000000..d2716a6 --- /dev/null +++ b/tools.lua @@ -0,0 +1,50 @@ +-- SWORDS DEFAULT +minetest.override_item("default:sword_diamond", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:sword_wood", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:sword_stone", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:sword_steel", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:sword_bronze", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:sword_mese", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +-- AXE DEFAULT +minetest.override_item("default:axe_diamond", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:axe_wood", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:axe_stone", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:axe_steel", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:axe_bronze", { + wield_scale = {x=1.5, y=2, z=1}, +}) + +minetest.override_item("default:axe_mese", { + wield_scale = {x=1.5, y=2, z=1}, +}) +