commit e6f560d9b13d833fc06f235d2e7039a061b28d65 Author: GreenDimond <24834740+GreenXenith@users.noreply.github.com> Date: Mon Oct 14 19:58:40 2019 -0700 Initial commit diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..db9b17d --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +MIT Copyright 2019 GreenDimond + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/modpack.txt b/modpack.txt new file mode 100644 index 0000000..bb9a02c --- /dev/null +++ b/modpack.txt @@ -0,0 +1 @@ +share all the things diff --git a/shared/depends.txt b/shared/depends.txt new file mode 100644 index 0000000..bfd3b59 --- /dev/null +++ b/shared/depends.txt @@ -0,0 +1 @@ +areas \ No newline at end of file diff --git a/shared/init.lua b/shared/init.lua new file mode 100644 index 0000000..b853823 --- /dev/null +++ b/shared/init.lua @@ -0,0 +1,24 @@ +shared = {} + +function shared.is_owner(pos, name) + if minetest.check_player_privs(name, areas.adminPrivs) then + return true + end + if minetest.get_meta(pos):get_string("owner") == name then + return true + end + return false +end + +function shared.can_interact(pos, name) + if shared.is_owner(pos, name) then + return true + end + local owners = areas:getNodeOwners(pos) + for _, owner in pairs(owners) do + if owner == name then + return true + end + end + return false +end \ No newline at end of file diff --git a/shared/textures/shared_lock.png b/shared/textures/shared_lock.png new file mode 100644 index 0000000..8e7ffd2 Binary files /dev/null and b/shared/textures/shared_lock.png differ diff --git a/shared_chest/depends.txt b/shared_chest/depends.txt new file mode 100644 index 0000000..3e27710 --- /dev/null +++ b/shared_chest/depends.txt @@ -0,0 +1,2 @@ +default +shared diff --git a/shared_chest/description.txt b/shared_chest/description.txt new file mode 100644 index 0000000..c180bf2 --- /dev/null +++ b/shared_chest/description.txt @@ -0,0 +1 @@ +Adds shared chests (built for areas mod). diff --git a/shared_chest/init.lua b/shared_chest/init.lua new file mode 100644 index 0000000..63ec613 --- /dev/null +++ b/shared_chest/init.lua @@ -0,0 +1,225 @@ +if not minetest.global_exists("shared") then + minetest.log("error", "mod 'shared_chest' depends on mod 'shared' (not found).") + return +end + +local F = minetest.formspec_escape + +local rim = "^shared_rim.png" + +minetest.register_node("shared_chest:shared_chest", { + description = "Shared Chest", + tiles = {"default_chest_top.png"..rim, "default_chest_top.png"..rim, "default_chest_side.png"..rim, + "default_chest_side.png"..rim, "default_chest_side.png"..rim, "default_chest_lock.png^shared_lock.png"..rim}, + paramtype2 = "facedir", + groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, +-- Pipeworks + tube = { + insert_object = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:add_item("main", stack) + end, + can_insert = function(pos, node, stack, direction) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:room_for_item("main", stack) + end, + input_inventory = "main", + connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1} + }, + legacy_facedir_simple = true, + sounds = default.node_sound_wood_defaults(), + on_construct = function(pos) + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + meta:set_string("infotext", "Shared Chest") + meta:set_string("name", "") + inv:set_size("main", 8 * 4) + end, + + after_place_node = function(pos, placer, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + + meta:set_string("owner", placer:get_player_name()) + end, + + can_dig = function(pos,player) + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if inv:is_empty("main") then + + if shared.is_owner(pos, player:get_player_name()) then + return true + end + end + end, + + on_metadata_inventory_put = function(pos, listname, index, stack, player) + + minetest.log("action", player:get_player_name().." moves stuff to protected chest at "..minetest.pos_to_string(pos)) + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + + minetest.log("action", player:get_player_name().." takes stuff from protected chest at "..minetest.pos_to_string(pos)) + end, + + 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 inside protected chest at "..minetest.pos_to_string(pos)) + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + + if not shared.can_interact(pos, player:get_player_name()) then + return 0 + end + + return stack:get_count() + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + + if not shared.can_interact(pos, player:get_player_name()) then + return 0 + end + + return stack:get_count() + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + + if not shared.can_interact(pos, player:get_player_name()) then + return 0 + end + + return count + end, + + on_rightclick = function(pos, node, clicker) + + if not shared.can_interact(pos, clicker:get_player_name()) then + return + end + + local meta = minetest.get_meta(pos) + + if not meta then + return + end + + 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;]" + .. "button[0,4.5;2,0.25;toup;" .. F("To Chest") .. "]" + .. "field[2.3,4.8;4,0.25;chestname;;" + .. meta:get_string("name") .. "]" + .. "button[6,4.5;2,0.25;todn;" .. F("To Inventory") .. "]" + .. "list[current_player;main;0,5;8,1;]" + .. "list[current_player;main;0,6.08;8,3;8]" + .. "listring[nodemeta:" .. spos .. ";main]" + .. "listring[current_player;main]" + + minetest.show_formspec( + clicker:get_player_name(), + "shared_chest:shared_chest_" .. minetest.pos_to_string(pos), + formspec) + end, + + on_blast = function() end, +}) + +-- Shared Chest recipes + +minetest.register_craft({ + output = 'shared_chest:shared_chest', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'default:copper_ingot', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = 'shared_chest:shared_chest', + recipe = {'default:chest', 'default:copper_ingot'}, +}) + +-- Shared Chest formspec buttons + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if not formname:find("^shared_chest:shared_chest_") then + return + end + + local pos = minetest.string_to_pos(formname:gsub("^shared_chest:shared_chest_", "")) + + if minetest.is_protected(pos, player:get_player_name()) then + return + end + + local meta = minetest.get_meta(pos); if not meta then return end + local chest_inv = meta:get_inventory() ; if not chest_inv then return end + local player_inv = player:get_inventory() + local leftover + + if fields.toup then + + -- copy contents of players inventory to chest + for i, v in ipairs(player_inv:get_list("main") or {}) do + + if chest_inv:room_for_item("main", v) then + + leftover = chest_inv:add_item("main", v) + + player_inv:remove_item("main", v) + + if leftover + and not leftover:is_empty() then + player_inv:add_item("main", v) + end + end + end + + elseif fields.todn then + + -- copy contents of chest to players inventory + for i, v in ipairs(chest_inv:get_list("main") or {}) do + + if player_inv:room_for_item("main", v) then + + leftover = player_inv:add_item("main", v) + + chest_inv:remove_item("main", v) + + if leftover + and not leftover:is_empty() then + chest_inv:add_item("main", v) + end + end + end + + elseif fields.chestname then + + -- change chest infotext to display name + if fields.chestname ~= "" then + + meta:set_string("name", fields.chestname) + meta:set_string("infotext", + "Shared Chest ("..fields.chestname..")") + else + meta:set_string("infotext", "Shared Chest") + end + + end +end) diff --git a/shared_chest/textures/shared_rim.png b/shared_chest/textures/shared_rim.png new file mode 100644 index 0000000..f3c4e3c Binary files /dev/null and b/shared_chest/textures/shared_rim.png differ diff --git a/shared_doors/depends.txt b/shared_doors/depends.txt new file mode 100644 index 0000000..836c474 --- /dev/null +++ b/shared_doors/depends.txt @@ -0,0 +1,3 @@ +default +doors +shared diff --git a/shared_doors/description.txt b/shared_doors/description.txt new file mode 100644 index 0000000..9cd8df0 --- /dev/null +++ b/shared_doors/description.txt @@ -0,0 +1 @@ +Adds shared doors and trapdoors (built for areas mod). diff --git a/shared_doors/init.lua b/shared_doors/init.lua new file mode 100644 index 0000000..472f5f5 --- /dev/null +++ b/shared_doors/init.lua @@ -0,0 +1,292 @@ +if not minetest.global_exists("shared") then + minetest.log("error", "mod 'shared_chest' depends on mod 'shared' (not found).") + return +end + +local function replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("doors_owner") + if owner and owner ~= "" then + meta:set_string("owner", owner) + meta:set_string("doors_owner", "") + end +end + +--[[ Doors ]]-- + +-- table used to aid door opening/closing +local transform = { + { + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, + }, + { + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, + }, + { + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, + }, + { + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, + }, +} + +local function can_dig_door(pos, digger) + replace_old_owner_information(pos) + if default.can_interact_with_node(digger, pos) or shared.can_interact(pos, digger) then + return true + else + minetest.record_protection_violation(pos, digger:get_player_name()) + return false + end +end + +local function door_toggle(pos, node, clicker) + local meta = minetest.get_meta(pos) + node = node or minetest.get_node(pos) + local def = minetest.registered_nodes[node.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 node.name:sub(-2) == "_b" then + state = 2 + else + state = 0 + end + else + state = tonumber(state) + end + + replace_old_owner_information(pos) + + -- until Lua-5.2 we have no bitwise operators :( + if state % 2 == 1 then + state = state - 1 + else + state = state + 1 + end + + local dir = node.param2 + if state % 2 == 0 then + minetest.sound_play(def.door.sounds[1], + {pos = pos, gain = 0.3, max_hear_distance = 10}) + else + minetest.sound_play(def.door.sounds[2], + {pos = pos, gain = 0.3, max_hear_distance = 10}) + end + + minetest.swap_node(pos, { + name = name .. transform[state + 1][dir+1].v, + param2 = transform[state + 1][dir+1].param2 + }) + meta:set_int("state", state) + + return true +end + +local function register_shared_door(name, def) + if not def.protected then + def.protected = false + end + + doors.register("shared_doors:door_shared_"..name, { + tiles = {{name = "doors_door_"..name..".png^shared_door_lock.png", backface_culling = true}}, + description = "Shared "..name:gsub("^%l", string.upper).." Door", + inventory_image = "doors_item_"..name..".png^shared_lock.png", + protected = def.protected, + groups = def.groups, + sounds = def.sounds, + sound_open = "doors_"..def.toggle_sound.."_open", + sound_close = "doors_"..def.toggle_sound.."_close", + }) + + minetest.override_item("shared_doors:door_shared_"..name.."_a", { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if shared.can_interact(pos, clicker:get_player_name()) then + door_toggle(pos, node, clicker) + return itemstack + end + end, + + can_dig = can_dig_door + }) + + minetest.override_item("shared_doors:door_shared_"..name.."_b", { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if shared.can_interact(pos, clicker:get_player_name()) then + door_toggle(pos, node, clicker) + return itemstack + end + end, + + can_dig = can_dig_door + }) + + minetest.register_craft({ + type = "shapeless", + output = "shared_doors:door_shared_"..name, + recipe = {"doors:door_"..name, "default:copper_ingot"}, + }) + + local item = def.craft_item + + minetest.register_craft({ + output = "shared_doors:door_shared_"..name, + recipe = { + {item, item}, + {item, "default:copper_ingot"}, + {item, item} + } + }) +end + +register_shared_door("wood", { + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + toggle_sound = "door", + craft_item = "group:wood", +}) + +register_shared_door("steel", { + protected = true, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), + toggle_sound = "steel_door", + craft_item = "default:steel_ingot", +}) + +register_shared_door("glass", { + groups = {cracky=3, oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), + toggle_sound = "glass_door", + craft_item = "default:glass", +}) + +register_shared_door("obsidian_glass", { + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + toggle_sound = "glass_door", + craft_item = "default:obsidian_glass", +}) + +--[[ Trap Doors ]]-- + +local function trapdoor_toggle(pos, node, clicker) + node = node or minetest.get_node(pos) + + replace_old_owner_information(pos) + + local def = minetest.registered_nodes[node.name] + + if string.sub(node.name, -5) == "_open" then + minetest.sound_play(def.sound_close, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.swap_node(pos, {name = string.sub(node.name, 1, + string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) + else + minetest.sound_play(def.sound_open, + {pos = pos, gain = 0.3, max_hear_distance = 10}) + minetest.swap_node(pos, {name = node.name .. "_open", + param1 = node.param1, param2 = node.param2}) + end +end + +local function register_shared_trapdoor(name, def) + if not def.protected then + def.protected = false + end + + if not def.texture then + def.texture = "doors_trapdoor_"..name + end + + doors.register_trapdoor("shared_doors:trapdoor_shared_"..name, { + description = name:gsub("^%l", string.upper).." Trapdoor", + inventory_image = def.texture..".png^shared_lock.png", + wield_image = def.texture..".png^shared_lock.png", + tile_front = def.texture..".png^shared_lock.png", + tile_side = def.texture.."_side.png", + protected = def.protected, + sounds = def.sounds, + sound_open = "doors_"..def.toggle_sound.."_open", + sound_close = "doors_"..def.toggle_sound.."_close", + groups = def.groups + }) + + minetest.override_item("shared_doors:trapdoor_shared_"..name, { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if shared.can_interact(pos, clicker:get_player_name()) then + trapdoor_toggle(pos, node, clicker) + return itemstack + end + end, + + can_dig = can_dig_door + }) + + minetest.override_item("shared_doors:trapdoor_shared_"..name.."_open", { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if shared.can_interact(pos, clicker:get_player_name()) then + trapdoor_toggle(pos, node, clicker) + return itemstack + end + end, + + can_dig = can_dig_door + }) + + if not def.amount then + def.amount = "" + end + + minetest.register_craft({ + output = "shared_doors:trapdoor_shared_"..name.." "..tostring(def.amount), + recipe = def.recipe + }) + + if def.recipe_shapless then + minetest.register_craft({ + type = "shapeless", + output = "shared_doors:trapdoor_shared_"..name, + recipe = def.recipe_shapless, + }) + end +end + +register_shared_trapdoor("wood", { + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, + sounds = default.node_sound_wood_defaults(), + toggle_sound = "door", + texture = "doors_trapdoor", + recipe = { + {"group:wood", "default:copper_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + }, + recipe_shapless = {"doors:trapdoor", "default:copper_ingot"}, + amount = 2, +}) + +register_shared_trapdoor("steel", { + protected = true, + groups = {cracky = 1, level = 2, door = 1}, + sounds = default.node_sound_metal_defaults(), + toggle_sound = "steel_door", + recipe = { + {"default:steel_ingot", "default:copper_ingot"}, + {"default:steel_ingot", "default:steel_ingot"}, + }, + recipe_shapless = {"doors:trapdoor_steel", "default:copper_ingot"}, +}) \ No newline at end of file diff --git a/shared_doors/textures/shared_door_lock.png b/shared_doors/textures/shared_door_lock.png new file mode 100644 index 0000000..917e8e4 Binary files /dev/null and b/shared_doors/textures/shared_door_lock.png differ